3

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

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

4 回答 4

7

它只是工作。内存将在您的异常处理块执行之前被释放。

于 2013-07-30T12:36:27.150 回答
3

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

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

18-如果上述76中描述的对象初始化的任何部分通过抛出异常而终止并且可以找到合适的释放函数,则调用释放函数以释放构造对象的内存,之后异常继续传播在新表达式的上下文中。如果找不到明确匹配的解除分配函数,则传播异常不会导致对象的内存被释放。[注:这适用于被调用的分配函数不分配内存的情况;否则,很可能导致内存泄漏。——尾注]

76) 这可能包括评估一个新的初始化器和/或调用一个构造器。

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

于 2013-07-30T13:20:57.797 回答
-1

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

item 的一个重要引用是:

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

对于具体的解决方案,我强烈建议你阅读这个项目(或者更好的是,整本书)。

于 2013-07-30T12:55:19.477 回答
-2

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

这是一个很好的问题,正确的处理需要一篇完整的文章。好消息有人已经写了那篇文章:构造函数失败

于 2013-07-30T13:26:41.737 回答