Ответ
Да, произойдет. Если исключение выбрасывается в теле конструктора после успешного выполнения new, выделенная память не будет освобождена автоматически. new в C++ выполняет два шага:
- Выделяет память (operator new).
- Вызывает конструктор.
Если конструктор завершается исключением, память, выделенная на шаге 1, не освобождается, так как полноценный объект не был создан и деструктор для него не будет вызван.
Пример утечки:
class Widget {
int* data;
public:
Widget(size_t size) {
data = new int[size]; // (1) Выделили память
// ... какая-то логика ...
if (some_condition) {
throw std::runtime_error("Construction failed"); // (2) Исключение!
}
// Память, выделенная для `data`, утекла.
}
~Widget() { delete[] data; }
};
void foo() {
try {
Widget* w = new Widget(100); // Утечка при исключении в конструкторе
} catch (...) { /* Память для w->data уже потеряна */ }
}
Решение: Использовать умные указатели (std::unique_ptr, std::shared_ptr) или технику RAII для управления сырыми ресурсами внутри класса до того, как может быть выброшено исключение.
Исправленный вариант:
#include <memory>
class SafeWidget {
std::unique_ptr<int[]> data; // RAII-обертка
public:
SafeWidget(size_t size) : data(std::make_unique<int[]>(size)) {
// Память уже управляется unique_ptr.
if (some_condition) {
throw std::runtime_error("Failed");
}
// При выбросе исключения деструктор unique_ptr освободит память.
}
// Деструктор по умолчанию корректен.
};