Ney*_*r87 3 c++ memory-leaks exception c++11
我读了Paul Deitel的《C++ How to Program 8th Edition》一书。第 645 页有一个声明:
当在 new 表达式中创建的对象的构造函数抛出异常时,会释放该对象动态分配的内存。
为了验证这个说法,我编写了如下代码:
#include <iostream>
#include <exception>
#include <memory>
class A{
public:
  A(){std::cout << "A is coming." << std::endl;}
  ~A(){std::cout << "A is leaving." << std::endl;}
};
class B
{
public:
  B()
  {
    std::cout << "B is coming." << std::endl;
    A b;
    throw 3;
  }
  ~B(){std::cout << "B is leaving." << std::endl;}
};
int main(void)
{
    try
    {
        std::shared_ptr<B> pi(new B);
    }
    catch(...)
    {
      std::cout << "Exception handled!" << std::endl;
    }
}
输出是:
B is coming.
A is coming.
A is leaving.
Exception handled!
这表明B的析构函数没有被调用,这似乎与上面的说法相冲突。
我的代码是否正确以验证该声明?如果不是,我应该如何修改?如果是的话,是否说明这个说法是错误的?
你混淆了两件事:
\n\n你已经证明后者不会发生,这是有道理的:你怎么能摧毁那些没有正确建造的东西呢?但请注意,成员变量的析构函数将被调用,因为当构造函数抛出异常时,所有成员变量都已完全构造完毕。
\n\n但这与内存释放无关,内存释放肯定会发生。
\n\n\n\n\n
[C++11: 15.2/2]:任何存储持续时间的对象,其初始化或销毁因异常而终止,将为它的所有完全构造的子对象(不包括类联合类的变体成员)执行析构函数,即,对于其主构造函数( 12.6.2) 已完成执行,析构函数尚未开始执行。类似地,如果对象的非委托构造函数已完成执行,并且该对象的委托构造函数因异常退出,则将调用 object\xe2\x80\x99s 析构函数。如果对象是在 new 表达式中分配的,则调用匹配的释放函数(3.7.4.2、5.3.4、12.5)(如果有)来释放该对象占用的存储空间。