簡體   English   中英

當你在 C++ 中釋放一個指針兩次或更多次時會發生什么?

[英]What happens when you deallocate a pointer twice or more in C++?

int main() {
    Employee *e = new Employee();

    delete e;
    delete e;
    ...
    delete e;
    return 0;
}

如果您嘗試多次通過指針delete對象,則會出現未定義的行為

這意味着幾乎任何事情都可能發生,從“似乎可以工作”到“崩潰”或完全隨機的事情。

這是未定義的行為,所以任何事情都可能發生。

可能發生的事情很糟糕。 通常,空閑存儲是一個精心管理的空閑塊和已分配塊系統, newdelete簿記以保持所有內容處於一致狀態。 如果再次delete ,系統很可能對無效數據做同樣的記賬,突然空閑存儲處於不一致狀態。 這被稱為“堆損壞”。

一旦發生這種情況,您對newdelete執行的任何操作都可能會產生不可預測的結果,其中可能包括嘗試在應用程序的內存區域之外寫入、默默地破壞數據、錯誤地認為沒有更多內存,或者重復分配或重疊分配。 如果幸運的話,該程序很快就會崩潰,盡管您仍然無法找出原因。 如果你不走運,它會繼續運行,結果很糟糕。

除了關於“未定義行為”的舊觀點,這意味着任何事情都可能發生,從無到有到通往在主內存中打開的地獄第七圈的網關,實際上,在大多數實現中通常會發生的是程序將繼續運行刪除,然后在某個不相關的內存分配中神秘地崩潰。

您可能正在冒險進入“未定義行為”領域。

在許多系統上,這會導致崩潰; 例如,在我的 Linux 機器上:

*** glibc detected *** ./cctest: double free or corruption (fasttop): 0x0000000000d59900 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f399f4cbdd6]
/lib/libc.so.6(cfree+0x6c)[0x7f399f4d074c]
./cctest[0x400a7a]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f399f474abd]
./cctest[0x400959]

如果你真的很幸運,它會崩潰。 通常情況下,它會存儲業力,直到您的 CEO 向您最重要的新客戶演示代碼時,它會損壞/破壞他們的所有數據。

在檢查或調試版本中,這種事情通常會被捕獲,但它可能完全未被發現並在以后造成嚴重破壞。 當涉及多個線程時,這一點尤其重要。

如果您擔心這可能會發生在您的應用程序中,要么完全停止使用原始指針,這樣您就不需要刪除(例如切換到shared_ptr ),或者在您之后始終將指針設置為NULL (或 0,或者最好還是nullptr )刪除它們。 對空指針調用 delete 保證什么都不做。

這不安全,並且不確定實際可能發生的情況:

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM