[英]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;
}
如果Hello1
和Hello2
引发异常, 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.