【问题标题】:The array won't be deallocated here when the constructor throws, right? [duplicate]当构造函数抛出时,数组不会在这里被释放,对吧? [复制]
【发布时间】:2014-02-11 01:18:15
【问题描述】:

这是潜在的内存泄漏,对吗?如果构造函数抛出,arr 不会被释放,对吧?我已经读过在这种情况下不会调用析构函数,但是 badType 的任何子对象都会被调用,但是我认为数组不会在这里,因为它是一个原始指针,对吗?

class badType
{
private:
    int* arr;
    int myLen, myNum;
public:
    badType(int myLen, int aNum)
    {
        this->myLen = myLen;
        arr = new int[myLen];

        if (aNum < 100) 
            throw exception{ "Da number is too low" };

        myNum = aNum;
    }

    ~badType()
    {
        delete[] arr;
    }
};

【问题讨论】:

  • 好问题,我想我在这里找到了一个回答你问题的副本:stackoverflow.com/questions/147572/…
  • 在这种特殊情况下,您可以在分配 arr 之前测试 aNum &lt; 100
  • 为什么不将cout&lt;&lt;"destructor called\n"; 弹出到析构函数中?
  • 另一个可能的答案here
  • @svenoaks 而且,您分配的金额myLen,不是mylen。不要命名差异如此之小的东西!

标签: c++


【解决方案1】:

不,它不会解除分配。如果构造函数抛出aNum &lt; 100,这将是内存泄漏。

初始化或销毁因异常终止的任何存储持续时间的对象将 为其所有完全构造的子对象(不包括 a 的变体成员)执行析构函数 union-like 类),即对于主要构造函数(12.6.2)已完成执行的子对象 并且析构函数还没有开始执行。

标准通常不会明确声明不会调用某些内容。因此,通过仅声明将调用完全构造的子对象的析构函数,标准相当于说不会调用对象自己的析构函数。

但是,如果对象是在空闲存储区分配的,它本身就会被释放。

如果对象是在新表达式中分配的,则匹配的释放 调用函数(3.7.4.2、5.3.4、12.5)(如果有)以释放对象占用的存储空间。

【讨论】:

  • 你有标准报价吗?
  • @svenoaks 动态存储不会自行释放。因此,如果不调用析构函数,则意味着它肯定不会被释放。
  • @svenoaks:我编辑了答案以添加您想要的报价。
  • 我不认为“完全”加强是正确的,因为它不是一个对象?但足够接近了,谢谢。
  • 实际上不会调用析构函数。但是,我不认为标准明确要求这种行为。对吗?
【解决方案2】:

你是对的,数组不会被释放。

一个对象只有在完全构造的情况下才会被销毁,即没有异常 从其构造函数传播。

阅读:RAII

【讨论】:

    猜你喜欢
    • 2018-02-10
    • 2019-08-12
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 2013-10-01
    相关资源
    最近更新 更多