[英]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.