繁体   English   中英

构造函数引发异常时删除运算符segfaults

[英]Delete operator segfaults when the constructor throws an exception

最好从代码开始以了解这一点

#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引发异常, Hello1 segfault 但是,如果我添加

Hello h = NULL;

有用!!!

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

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

但是如果我添加Hello h = NULL; 有用!!! 为什么在哪里...解释! 请。

这是因为当指针为null时, operator delete不会执行任何operator delete 期望什么都不做,这是标准行为。 C ++ 11标准的3.7.4.2段规定:

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

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

根据第5.3.5 / 2段:

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

为什么在哪里...解释! 请。

如果Hello的构造函数throw h从未初始化delete尝试读取该未初始化的变量和未定义的行为。

我建议使用智能指针。

如果您尝试删除不应删除的内容,则delete可能会引发异常。 正如其他人所指出的那样, delete不会抛出,如果您尝试删除一些设置为null

new会,据我所知,从来没有扔,除非你是内存不足。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM