谁删除了在“新建"期间分配的内存?构造函数中有异常的操作?

Who deletes the memory allocated during a quot;newquot; operation which has exception in constructor?(谁删除了在“新建期间分配的内存?构造函数中有异常的操作?)
本文介绍了谁删除了在“新建"期间分配的内存?构造函数中有异常的操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我真的不敢相信我找不到明确的答案...

在使用 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.

这篇关于谁删除了在“新建"期间分配的内存?构造函数中有异常的操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How do compilers treat variable length arrays(编译器如何处理变长数组)
Deduce template argument from std::function call signature(从 std::function 调用签名推导出模板参数)
check if member exists using enable_if(使用 enable_if 检查成员是否存在)
Standard Library Containers with additional optional template parameters?(具有附加可选模板参数的标准库容器?)
Uses of a C++ Arithmetic Promotion Header(C++ 算术提升标头的使用)
Parameter pack must be at the end of the parameter list... When and why?(参数包必须位于参数列表的末尾...何时以及为什么?)