【问题标题】:Delete operator segfaults when the constructor throws an exception构造函数抛出异常时删除操作符段错误
【发布时间】:2013-04-26 09:36:26
【问题描述】:

最好从代码开始理解这一点

#include "Hello1.h"
#include "Hello2.h"

int main(int argc, char ** argv)
{
    // Hello1 and Hello2 are derevied classes of Hello
    // And there constructor throws an exception
    Hello * h;

    try
    {
        if (argv[1][0]=='1')
            h = new Hello1;
        else
            h = new Hello2;
    }
    catch (std::exception ex) { /*print error*/ }

    delete h;
}

如果Hello1Hello2 抛出异常,它segfault。但是,如果我添加

Hello h = NULL;

有效!!!

Hello 是一个带有抛出异常的构造函数的类

我能想到的就是构造函数中的异常从内存中删除对象!为什么在哪里谁...解释!请。

【问题讨论】:

  • 什么是Hellotypedef 是指针类型还是可以从自己的指针构造的类型?
  • 如果h不是指针,h = new Hello1;如何编译?或者你的意思是Hello* h
  • @Andy Prowl 你是对的,对不起,我是凭记忆写的。
  • 什么是Exception?所以你的意思是std::exception
  • @Angel.King.47:请不要“凭记忆写”,请确保您实际发布的代码编译并生成您发布的实际错误。这样可以避免每个人都追随红鲱鱼。

标签: c++ class exception delete-operator


【解决方案1】:

但是,如果我添加 Hello h = NULL; 它会起作用!!!为什么在哪里谁...解释!请。

这是因为当指针为null 时,operator delete 什么都不做。预计什么都不做,这是标准行为。 C++11 标准第 3.7.4.2 段规定:

[...] 提供给释放函数的第一个参数可能是空指针值;如果是这样,如果释放 函数是标准库中提供的,调用无效。 [...]

如果不是null,另一方面,operator delete 会尝试删除hello 指向的对象,并且由于指针未初始化(因为构造抛出并且控制被转移到异常处理程序在分配给hello 之前),您会得到未定义的行为

根据第 5.3.5/2 段:

[...] 在第一种选择(delete object)中,delete 的操作数的值可能是空指针 value,指向由先前的 new 表达式创建的非数组对象的指针,或指向子对象的指针 (1.8) 表示这种对象的基类(第 10 条)。 如果不是,则行为未定义。 [...]

【讨论】:

  • 所以我认为构造函数中抛出的任何异常总是确定类未定义。
  • @Angel.King.47:我认为你想说的是正确的话,但方式不准确。对象的生命周期从其初始化完成时开始。对于类类型,这是构造函数返回的时间。由此得出的结论是,如果在构造函数中抛出异常,则该对象永远不会开始存在。如果这是您的意思,那么答案是“是”。
  • 完美,“如果在构造函数中抛出异常,则对象永远不会开始存在。”正是我需要的。
  • 注意:如果您在抛出异常之前在构造函数中分配了其他动态内存(通过new),则您有责任在抛出之前清理它。
【解决方案2】:

为什么在哪里……解释一下!请。

如果 Hello 的构造函数抛出 h 永远不会初始化 - delete 会尝试读取未初始化的变量和未定义的行为。

我建议使用智能指针。

【讨论】:

    【解决方案3】:

    delete 可能会在您尝试删除不应删除的内容时抛出异常。正如其他人指出的那样,如果您尝试删除设置为 null 的内容,delete 将不会抛出

    new 据我所知,除非你内存不足,否则永远不会抛出。

    所以发生的情况是argv[1] 不是'1',这意味着 h 指向未知的东西,这使得delete 抛出异常

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2018-01-28
      • 2016-07-18
      • 2011-11-04
      • 2016-04-12
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多