Что происходит с памятью, выделенной `new`, если конструктор выбрасывает?

Будет ли этот код вызывать утечку памяти?

#include <stdexept>

class MyClass
{
public:
    MyClass()
    {
        throw std::runtime_error("Test");
    }
};

int main()
{
    try
    {
        MyClass * myClass = new MyClass;
    }
    catch (const std::exception & exc)
    {
        // Memory leak?
    }
    return 0;
}

Память, выделенная new, никогда не удаляется. Это позаботится о себе, или это настоящая утечка памяти?

Ответы

Ответ 1

Память будет автоматически освобождена до того, как будет распространяться исключение.

Это важно, потому что: а) программа никогда не получает указатель на свободный, и б) даже если бы это произошло, у него не было бы портативного способа фактически освободить его, поскольку память никогда не становилась объектом, который можно удалить.

Ответ 2

Память будет правильно освобождена.

Связанные вопросы в SO.

Нельзя ли вообще исключить исключение в конструкторе?   С++: обрабатывать ресурсы, если конструкторы могут генерировать исключения (ссылка на часто задаваемые вопросы 17.4)
[email protected] ~ $ cat noleak.cpp && g++ noleak.cpp && valgrind --leak-check=full ./a.out
#include <stdexcept>

class MyClass
{
public:
    MyClass()
    {
        throw std::runtime_error("Test");
    }
};

int main()
{
    try
    {
        MyClass * myClass = new MyClass;
    }
    catch (const std::exception & exc)
    {
        // Memory leak?
    }
    return 0;
}
==3652== Memcheck, a memory error detector
==3652== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3652== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==3652== Command: ./a.out
==3652== 
==3652== 
==3652== HEAP SUMMARY:
==3652==     in use at exit: 0 bytes in 0 blocks
==3652==   total heap usage: 3 allocs, 3 frees, 106 bytes allocated
==3652== 
==3652== All heap blocks were freed -- no leaks are possible
==3652== 
==3652== For counts of detected and suppressed errors, rerun with: -v
==3652== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6)
[email protected] ~ $ 

Ответ 3

$15.2/2 - "Объект, который частично построенный или частично разрушенный будут уничтожены деструкторы для всех его полностью построенных базовых классов и невариантные члены, то есть для подобъекты, для которых основной конструктор (12.6.2) завершен исполнение и деструктор не но начатое исполнение. Аналогично, если конструктор без делегирования для объект завершил выполнение и делегирующий конструктор для этого объекта выходы с исключением, объекты деструктор будет вызван. Если объект был выделен в новое выражение, соответствие функция освобождения (3.7.4.2, 5.3.4, 12.5), если таковой имеется, вызывается для освобождения памяти, занимаемой объектом."