我用,当你扔在一个动态分配的类的异常会发生什么有些同事辩论。 我知道malloc
被调用,然后在类的构造函数。 构造函数永远不会返回,所以会发生什么情况malloc
?
请看下面的例子:
class B
{
public:
B()
{
cout << "B::B()" << endl;
throw "B::exception";
}
~B()
{
cout << "B::~B()" << endl;
}
};
void main()
{
B *o = 0;
try
{
o = new B;
}
catch(const char *)
{
cout << "ouch!" << endl;
}
}
碰巧的malloc内存什么o
,它泄露? 请问CRT搭上构造函数的异常和释放内存?
干杯!
丰富
呼叫到
new B();
解决了两件事情:
- 与操作员分配新的()(或者全局的一种或一类特定的一个,潜在地放置一个具有语法
new (xxx) B()
- 调用构造函数。
如果构造函数抛出,相应的操作员删除被调用。 其中相应的删除是一个放置的情况是放置delete运算符被称为无语法的唯一情况::运算符delete()。 delete x;
或delete[] x;
不叫位置删除运营商并没有类似的语法来放置新的给他们打电话。
请注意,而B的析构函数将不会被调用,已建成的子对象(成员或B的B和基类)将被破坏之前调用delete运算符。 这不叫构造函数是一个B.
当异常是从构造函数抛出的,由新分配的内存被释放,但B类的析构函数没有被调用。
In this case, your object, o, does not actually get constructed, and the memory allocated by new is freed. As such, the destructor does not get called. So you do NOT need to call:
delete o;
An interesting design pattern is RAII -- Resource Acquisition Is Initialization. In this pattern, you use a constructor to encapsulate the acquisition of a resource, and release the resource in the destructor. If the resource can not be acquired, you throw in the constructor -- much like your example. Thus if you have a valid object, you have the resource.
If the object is constructed, then you have successfully acquired the resource. This means that for the life of the object, you own the resource. When the object is deleted, the resource is released. If the object is never constructed, then you never acquired the resource. See wikipedia:
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
从C ++ 2003标准5.3.4 / 17 - 新:
如果能够找到通过抛出异常和合适的释放函数上述终止描述的对象初始化的任何部分,解除分配函数被调用,以释放在其中被构造的对象的存储器,之后将异常继续在上下文中传播的新的表达。 如果找不到丝毫不含糊匹配的释放函数,传播异常不会导致该对象的内存被释放。 [注:当被叫分配功能不分配存储器这是合适的; 否则,它是很容易造成内存泄漏。 ]
因此,有可能会或可能不会泄漏 - 这取决于合适的释放器是否可以发现(这是正常的情况下,除非运营商新/删除已被覆盖)。在那里有一个合适的释放器的情况下,编译器负责在它的调用如果构造函数抛出接线。
请注意,这或多或少无关发生什么在构造函数中,这是我在回答第一次讨论收购资源 - 并且是在许多常见问题,文章和帖子讨论的问题。