在构造“新”对象期间发生异常时,堆分配的内存会发生什么?

时间:2013-07-30 12:35:26

标签: c++ memory

当一个类在构造期间抛出异常时,分配的内存会发生什么变化,你将如何处理这样的事情。例如:

std::auto_ptr<ThirdPartyClass> au_tpc;

try
{
    au_tpc.reset(new ThirdPartyClass());
}
catch(...)
{
    // What happened to the memory allocated of 
    // sizeof(ThirdPartyClass) for the new instance?
}

4 个答案:

答案 0 :(得分:7)

它只是有效。在执行异常处理块之前,将释放内存。

答案 1 :(得分:2)

C ++ 11标准的相关部分: 5.3.4 [expr.new]

  

8 - new-expression通过调用分配函数(3.7.4.1)获取对象的存储空间。如果新的 -   表达式通过抛出异常终止,它可以通过调用释放函数来释放存储(3.7.4.2)。如果分配的类型是非数组类型,则分配函数的名称为operator new和   释放函数的名称是operator delete。如果分配的类型是数组类型,则分配   函数的名称为operator new[],解除分配函数的名称为operator delete[]

     

18 - 如果上面描述的对象初始化的任何部分 76 通过抛出异常和合适的方式终止   可以找到deallocation函数,调用deallocation函数来释放对象所在的内存   正在构建,之后异常继续在new-expression的上下文中传播。   如果找不到明确的匹配解除分配函数,则不会传播异常   要释放的对象的内存。 [注意:当被调用的分配函数没有时,这是合适的   分配记忆;否则,很可能导致内存泄漏。 - 结束说明]

     

76)这可能包括评估新的初始化程序和/或调用构造函数。

换句话说,内存将自动释放,除非在非常特殊的情况下,编译器无法找到正确的解除分配函数(例如,你弄乱了自定义(de)分配器,或者内存实际上不需要)被释放)。

答案 2 :(得分:-1)

查看Scoot Meyers书籍“更有效的C ++”的第10项。

项目的一个重要引用是:

  • C ++仅销毁完全构造的对象,并且在构造函数运行完成之前,对象尚未完全构造。”。因此,如果在构造函数中抛出异常并且不在构造函数中捕获它,则永远不会调用析构函数。

对于特定的解决方案,我强烈建议您阅读此项目(或更好,整本书)。

答案 3 :(得分:-2)

  

当一个类在构造期间抛出异常时,分配的内存会发生什么?你会如何处理这样的事情

这是一个很好的问题,正确的治疗需要一篇成熟的文章。有人写过这篇文章的好消息:Constructor Failures