c++ - 刪除指針后,是否將指針空?

  显示原文与译文双语对照的内容

我將開始說,使用智能指針,你將永遠不必擔心這個問題。

以下代碼有什麼問題?


Foo * p = new Foo;
//(use p)
delete p;
p = NULL;

這是由對另一個問題的回答和評論 。 來自 Neil的一個註釋生成了幾個 upvotes:

在刪除後設置指向空的指針不是 C++ 通用的好實踐。 有時候是一件好事,當它沒有意義並且可以隱藏錯誤時。

在很多情況下,它不能幫助。 但以我的經驗,它不能傷害。 有人啟發我。

时间: 原作者:

設置為null指針刪除它之後指出,當然不能傷害,但它通常是一個創可貼在一個更基本的問題: 為什麼在第一個地方使用指針? 我可以看到兩個典型的原因:

  • 你只是想在堆上分配一些東西。 在這種情況下,將它包裝在一個RAII對象中會更安全更乾淨。 不再需要對象時結束對象的登機範圍。 這就是 std::vector的工作原理,它解決了不小心留下指針到被釋放內存的問題。 沒有指針。
  • 或者你想要一些複雜的共享所有權語義。 從 new 返回的指針可能與 delete 調用的指針不同。 同時有多個對象同時使用了對象。 在這種情況下,一個共享指針或者類似的東西會更好。

我的經驗法則是如果你在用戶代碼中留下指針,你就會犯錯。 指針不應該在第一個位置指向垃圾。 為什麼沒有一個對象負責確保它的有效性? 為什麼pointed-to對象的作用域不結束?

原作者:

設置指向 0 ( 哪個是"空"在標準 C++ 中,從C 定義的空值有些不同)的指針避免在雙重刪除時崩潰。

請考慮以下事項:


Foo* foo = 0;//Sets the pointer to 0 (C++ NULL)
delete foo;//Won't do anything

而:


Foo* foo = new Foo();
delete foo;//Deletes the object
delete foo;//Undefined behavior 

換句話說,如果你沒有將已經刪除的指針設置為 0,那麼在進行雙重刪除時,你會遇到麻煩。 在刪除後設置指向 0的指針的參數是這樣做的,它只是屏蔽了 Bug 並使它們不被處理。

最好不要有雙重刪除 Bug,但是根據所有權語義和對象生命周期,這在實踐中很難實現。 我更喜歡一個被屏蔽的雙重刪除 Bug 。

最後,關於管理對象分配的小工具,我建議你查看 std::unique_ptr的嚴格/單數所有權,共享所有權的std::shared_ptr 或者其他智能指針實現,具體取決於你的需求。

首先,有很多關於這個和密切相關的主題的問題,例如 http://stackoverflow.com/questions/704466/why-doesnt-delete-set-the-pointer-to-null

在你的代碼中,在( 使用p ) 中發生的問題。 例如如果你有這樣的代碼:


Foo * p2 = p;

然後將p 設置為空就完成很少,因為你仍然有指針p2來擔心。

這並不是說設置一個指向NULL的指針總是毫無意義的。 例如如果是指向資源的成員變數,它的生存期與包含p的類不完全相同,那麼將p 設置為NULL的方法可能是表明資源存在與否的有用方法。

原作者:

我幾乎將我的delete ( 或者在我的案例中 free ) 指針設置為一個垃圾值:


char *ptr = malloc(...);
...
...
free(ptr);
ptr = 0xDEADBEEF;

這( 可能可能) 需要你的離堆指針,所以它不會腐敗的一切如果你double-delete,不崩潰。 它也將失敗( 因為它應該) 如果有人試圖使用它--和! 調試時很容易識別,因此你可以知道當你看到它時: "哦,我在試圖取消引用以前刪除的指針"。

話雖這麼說,這可能是一個非常糟糕的想法出於某種原因,我沒有想到,但似乎好了在我的腦海里。

原作者:

如果在 delete 之後有更多代碼,是。 當在構造函數中或者方法或者函數末尾刪除指針時,沒有。

這個比喻的要點是提醒程序員在run-time中,對象已經被刪除。

更好的做法是使用智能指針( 共享或者作用域),它自動刪除目標對象。

原作者:

就像其他人所說 delete ptr; ptr = 0; 不會讓惡魔飛出你的鼻子。 但是,它鼓勵使用 ptr 作為排序的標誌。 代碼充滿了 delete 並將指針設置為 NULL 。 下一步是散布 if (arg == NULL) return; 通過你的代碼來防止意外使用 NULL 指針。 當對 NULL的檢查成為檢查對象或者程序狀態的主要手段時發生這裡問題。

我確信有一個 代碼異味 關於使用指針作為標誌,但我沒有找到一個。

原作者:
...