谁删除在“新"期间分配的内存?构造函数中有异常的操作?
我真的不敢相信我找不到一个明确的答案......
在使用 new
操作符初始化的情况下,如何释放 C++ 类构造函数引发异常后分配的内存.例如:
class Blah{上市:废话(){抛出哎呀";}};无效的主要(){废话* b = NULL;尝试{b = 新的 Blah();}抓住 (...){//现在怎么办?}}
当我尝试这个时,b
在 catch 块中为 NULL(这是有道理的).
在调试时,我注意到控制在到达构造函数之前进入了内存分配例程.
MSDN 网站上的这个似乎证实了这一点:p><块引用>
当使用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.
相关文章