簡體   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