Будет ли утечка памяти, если конструктор бросит исключение?

Рейтинг: 4Ответов: 2Опубликовано: 07.03.2011

Есть некая фабрика:

TBar * foo()
{
    return new TBar();  // здесь конструктор TBar бросает исключение
}

Если конструктор TBar бросит исключение, мы получим утечку памяти, выделенной для нового объекта TBar. Верно?

Ответы

▲ 7Принят

Нет, неверно.

Если не рассматривать выделения памяти внутри конструктора TBar, то утечек не будет. В языке C++ объект считается созданным только в тот момент, когда его конструктор завершит выполнение без ошибок. Здесь этого не происходит, поэтому объект никогда не был создан, а, значит, и память под него "как бы" не выделялась. Т.е. компилятор обязан корректно освободить память, в которой будет находится объект, в случае исключения в его конструкторе.

▲ 8

Вот что написано в стандарте С++ 2011

15.2.2

An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.

В общем, если конструктор был прерван исключением, то вызываются деструкторы всех уже созданных объектов, а динамическая память, выделенная под основной класс, будет освобождена соответствующим delete.

Итого, утечки не будет, в том числе и при наличии базового класса, если, конечно, нет внутренних утечек памяти.