谁删除了在“新建"期间分配的内存?构造函数中有异常的操作?
我真的不敢相信我找不到明确的答案...
在使用 new
运算符初始化的情况下,如何释放 C++ 类构造函数抛出异常后分配的内存.例如:
class 废话{上市:废话(){抛出哎呀";}};无效主(){废话* b = NULL;尝试{b = new Blah();}抓住 (...){//现在怎么办?}}
当我尝试这样做时,catch 块中的 b
为 NULL(这是有道理的).
在调试时,我注意到控制在命中构造函数之前进入内存分配例程.
MSDN 网站上的这一点似乎证实了这一点::><块引用>
当new用于分配内存时对于 C++ 类对象,对象的构造函数在内存之后被调用已分配.
所以,记住局部变量 b
永远不会被赋值(即在 catch 块中为 NULL)你如何删除分配的内存?
如果能得到一个跨平台的答案也很好.即,C++ 规范是怎么说的?
澄清:我不是在谈论类在 c'tor 中自己分配内存然后抛出的情况.我很感激在这些情况下不会调用 d'tor.我说的是用于分配 THE 对象的内存(在我的例子中是 Blah
).
你应该参考类似的问题 此处 和此处.基本上,如果构造函数抛出异常,您就可以安全地再次释放对象本身的内存.虽然,如果在构造函数期间已经声明了其他内存,则在离开构造函数之前,您需要自行释放它,但有异常.
对于谁删除内存的问题,答案是 new-operator 背后的代码(由编译器生成).如果它识别出离开构造函数的异常,它必须调用类成员的所有析构函数(因为那些已经在调用构造函数代码之前成功构造)并释放它们的内存(可以与析构函数调用一起递归完成,很可能通过对它们调用适当的delete)以及释放为此类本身分配的内存.然后它必须将捕获的异常从构造函数重新抛出给 new 的调用者.当然,可能还有更多工作要做,但我无法从脑海中提取所有细节,因为它们取决于每个编译器的实现.
I really can't believe I couldn't find a clear answer to this...
How do you free the memory allocated after a C++ class constructor throws an exception, in the case where it's initialised using the new
operator. E.g.:
class Blah
{
public:
Blah()
{
throw "oops";
}
};
void main()
{
Blah* b = NULL;
try
{
b = new Blah();
}
catch (...)
{
// What now?
}
}
When I tried this out, b
is NULL in the catch block (which makes sense).
When debugging, I noticed that the conrol enters the memory allocation routine BEFORE it hits the constructor.
This on the MSDN website seems to confirm this:
When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.
So, bearing in mind that the local variable b
is never assigned (i.e. is NULL in the catch block) how do you delete the allocated memory?
It would also be nice to get a cross platform answer on this. i.e., what does the C++ spec say?
CLARIFICATION: I'm not talking about the case where the class has allocated memory itself in the c'tor and then throws. I appreciate that in those cases the d'tor won't be called. I'm talking about the memory used to allocate THE object (Blah
in my case).
You should refer to the similar questions here and here. Basically if the constructor throws an exception you're safe that the memory of the object itself is freed again. Although, if other memory has been claimed during the constructor, you're on your own to have it freed before leaving the constructor with the exception.
For your question WHO deletes the memory the answer is the code behind the new-operator (which is generated by the compiler). If it recognizes an exception leaving the constructor it has to call all the destructors of the classes members (as those have already been constructed successfully prior calling the constructor code) and free their memory (could be done recursively together with destructor-calling, most probably by calling a proper delete on them) as well as free the memory allocated for this class itself. Then it has to rethrow the catched exception from the constructor to the caller of new. Of course there may be more work which has to be done but I cannot pull out all the details from my head because they are up to each compiler's implementation.
相关文章