Что происходит с памятью, выделенной `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), если таковой имеется, вызывается для освобождения памяти, занимаемой объектом."