Чтобы ответить на последний вопрос:
Как бы я решил эту утечку памяти?
Нет утечки памяти.Утечка произошла бы только в том случае, если BadClass
сам динамически распределял контент и никогда не освобождал его в своем деструкторе.Поскольку мы не обращаем внимания на вашу BadClass
реализацию, а не занимаемся догадками, решать вам.Единственный способ new BadClass[N];
утечки памяти сам по себе - это когда она завершается, и вы позже выбрасываете единственную ссылку на нее, которой вы управляете вручную (array
).
Массив, динамически выделяемый, выбрасывая в пределах одногоиз конструкторов для содержащихся в них элементов будет (а) возвращать деструкторы в обратном порядке для уже созданных элементов, (б) освобождать выделенную память и, наконец, (в) обрабатывать фактический бросок ближайшему обработчику перехвата (или обработчику по умолчанию, когдаих нет).
Поскольку происходит сброс, присваивание результирующему указателю массива никогда не происходит и поэтому не требует delete[]
.
Лучше всего продемонстрировано на примере:
#include <iostream>
struct A
{
static int count;
int n;
A() : n(++count)
{
std::cout << "constructing " << n << '\n';
if (count >= 5)
throw std::runtime_error("oops");
}
~A()
{
std::cout << "destroying " << n << '\n';
}
};
int A::count;
int main()
{
A *ar = nullptr;
try
{
ar = new A[10];
}
catch(std::exception const& ex)
{
std::cerr << ex.what() << '\n';
}
}
Вывод
constructing 1
constructing 2
constructing 3
constructing 4
constructing 5
destroying 4
destroying 3
destroying 2
destroying 1
oops
Обратите внимание, что поскольку построение элемента '5' никогда не завершалось, егодеструктор не уволен.Однако члены, которые были успешно построены , разрушены (не показано в примере выше, но это забавное упражнение, если вы готовы к этому).
Всетем не менее, используйте умные указатели независимо.