2015-10-14 42 views
4

我試圖釋放同一個指針兩次,但失敗了,但是如果我按照相同的步驟使它不爲NULL,代碼運行正常。兩次釋放同一個指針不給錯誤,如果我讓指針爲空

#include <iostream> 

    struct MyClass { 
     MyClass() {std::cout << "Allocated and Constructed" << std::endl ;} 
    }; 

    int main() { 
     // allocates and constructs five objects: 
     MyClass * p1 = new MyClass[5]; 

     delete[] p1; 
     delete[] p1; // The code will succeed if I comment this line of code 
     p1=NULL; 
     delete[] p1; 
     delete[] p1; 

     return 0; 
    } 

我看到一個很好的回答這個問題,但What happens when you deallocate a pointer twice or more in C++?什麼使得它運行,如果我讓NULL,不應該是相同的行爲要遵循兩種情況?

+1

刪除NULL是明確的和什麼也不做。 – molbdnilo

+0

[是否可以安全地刪除NULL指針?](http://stackoverflow.com/questions/4190703/is-it-safe-to-delete-a-null-pointer) –

回答

6

你只需要你分配什麼取消分配。您將MyClassnew[]分配五個實例。所以這就是你需要釋放的東西。

你不重新分配任何指針。除非您動態分配指針,否則指針不需要解除分配,並且您的代碼不會動態分配任何指針。

當你使指針nullptr(或NULL),它不指向任何東西。所以調用delete就沒有效果。 C++標準選擇在空指針上調用delete(或delete[])什麼都不做。

+0

謝謝!,確實有我身邊的啤酒:) – Shrey

1

delete[] p1;不是通常情況下更改p1的實際值。 (雖然C++標準規定它可以可以設置爲p1nullptr這樣做,但我沒有編譯過的實際上是這樣做的)。

因此,第二次調用delete[] p1;時的行爲未定義,因爲程序不再擁有該內存。

有些程序員認爲在delete[]之後明確設置p1 = nullptr是好的做法,因爲後面的delete是良性的。但是,這樣做可以隱藏其他的內存管理問題你的程序有(爲什麼程序試圖delete的內存不止一次同一塊?),所以我會建議反對。

+1

雖然大多數程序員認爲這是不好的做法。 –

1

從標準,5.3.5 $ 2刪除[expr.delete](由我粗體)

在第一種方式(刪除對象)的 的操作數的值刪除可以是空指針值,指向由前一個新表達式創建的非數組對象 的指針或指向代表這樣的對象的基類(子句10)的子對象 (1.8)的指針。如果不是, 的行爲是未定義的。在第二種替代方案(刪除陣列)中, 刪除的操作數的值可以是空指針值或 由先前數組 new-expression產生的指針值。 如果不是,則行爲未定義。

它解釋了爲什麼刪除指針兩次的原因是UB,並且刪除了一個空指針是明確定義的。