2009-02-12 36 views
5
#define SAFE_DELETE(a) if((a) != NULL) delete (a); (a) = NULL; 

OR哪個版本的safe_delete更好?

template<typename T> void safe_delete(T*& a) { 
    delete a; 
    a = NULL; 
} 

或任何其他更好的辦法

+3

其仍然愚蠢,但宏安全刪除應該是:#define SAFE_DELETE(a)do {delete(a); (a)= NULL; } while(0) – 2009-02-12 14:28:50

回答

5

很明顯的功能,原因很簡單。宏多次評估其論證。這可能有不良副作用。此外,該功能可以作用域。沒有什麼比這更好的:)

5

一般來說,喜歡內聯函數在宏,因爲宏不尊重的範圍,並可以與預處理過程中的一些符號發生衝突,導致很奇怪的編譯錯誤。

當然,有時模板和函數不會這樣做,但在這裏並不是這樣。

此外,更好的安全刪除是不必要的,因爲您可以使用智能指針,因此不需要記住在客戶端代碼中使用此方法,而是封裝它。

編輯)正如其他人所指出的,安全的,刪除是不是安全,因爲即使有人不忘記使用它,它仍然可能沒有預期的效果。所以它實際上完全沒有價值,因爲正確使用safe_delete需要的不僅僅是自己設置爲0。

7

刪除a;

ISO C++指定,在NULL指針上刪除就不會執行任何操作。從ISO 14882

引用:

 
    5.3.5 Delete [expr.delete] 

    2 [...] In either alternative, if the value of the operand of delete is the 
     null pointer the operation has no effect. [...] 

問候,博多

/編輯:我沒有注意到一個= NULL;在原來的帖子中,如此新的版本:刪除一個;一個= NULL;然而,設置a = NULL的問題已經被指出(錯誤的安全感)。

+0

關於測試NULL和性能:我知道delete可以用NULL來調用,但是if(p!= NULL)是一個快速讀取操作,可以跳過函數調用和一個assignement(寫入記憶)。刪除if沒有錯,但初級程序員讀取它和性能如何? – 2016-02-10 15:51:25

+0

真的,另一方面:測試NULL是一個條件跳轉。如果以某種方式編寫代碼,通常不會釋放NULL指針,那麼您只需複製該條件跳轉,因爲您自己執行該操作,然後調用函數,然後再次執行。所以在我的選擇中,最好教導做適當的資源跟蹤而不是做NULL測試。 – 2016-03-21 16:06:03

2

您無需使用delete進行無效測試,它相當於無操作。 (a) = NULL讓我擡起眉毛。第二種選擇更好。

但是,如果您有選擇,您應該使用智能指針,如std::auto_ptrtr1::shared_ptr,這些指針已經爲您執行此操作。

+0

刪除時,auto_ptr和shared_ptr都不會設置爲NULL。 QPointer是我知道的唯一一個這樣做的課程。 – 2009-03-20 16:35:07

19

我不會說,因爲兩者都會給你一種虛假的安全感。例如,假設您有一個函數:

void Func(SomePtr * p) { 
    // stuff 
    SafeDelete(p); 
} 

您將p設置爲NULL,但函數外部的副本不受影響。

但是,如果您必須執行此操作,請使用模板 - 宏將始終有可能對其他名稱進行拼湊。

+0

好吧,一個瘋狂的傢伙正在潛伏着。上一個。這個答案是正確的... – gimpf 2009-02-12 11:44:23

+3

+1刪除它後將指針設置爲NULL很少有意義。 – 2009-02-12 14:32:33

2

我覺得

#define SAFE_DELETE(pPtr) { delete pPtr; pPtr = NULL }更好

  1. 其確定調用刪除如果PPTR爲NULL。所以如果檢查不是必需的。
  2. 如果您調用SAFE_DELETE(ptr + i),將導致編譯錯誤。
  3. 模板定義將爲每種數據類型創建函數的多個實例。在我看來,在這種情況下,這些多重定義不會增加任何價值。
  4. 此外,使用模板函數定義,您有函數調用的開銷。
0

正如前面提到的那樣,第二個是更好的一個,而不是一個有潛在副作用的宏,沒有對NULL的不需要的檢查(儘管我懷疑你是這樣做的一種類型檢查)等,但都不是很有希望的安全。如果您確實使用了類似tr1 :: smart_ptr的內容,請確保您閱讀了他們的文檔,並確保它具有適合您的任務的正確語義。我最近不得不尋找並清理了一個巨大的內存泄漏,這是由於同事將smart_ptrs放入具有循環鏈接的數據結構:)(他應該使用weak_ptrs作爲後向引用)

0

SAFE_DELETE的使用確實出現成爲C程序員的方法來控制C++中內置的內存管理。我的問題是:C++是否允許這種方法使用SAFE_DELETE指針已被適當封裝爲私人?這個宏只能用於聲明爲Public的指針嗎? OOP壞了!

0

我喜歡這個版本:

​​3210

刪除它是毫無意義的,因爲你會使用指針的唯一原因是,以允許在多個地方同時引用的對象後設置指針爲null 。即使程序的一部分中的指針爲0,也可能有其他的未設置爲0.

此外,safe_delete宏/函數模板非常難以正確使用,因爲它只有兩個地方可以使用,如果有代碼可能會拋出新的和刪除給定的指針。

1)無論是裏面的catch(...)塊重新拋出異常,毗鄰爲不丟的路徑趕上(...)塊也被複制。 (也可以在每個中斷旁邊複製,返回,繼續等等,這可能會使指針超出範圍)

2)在擁有指針的對象的析構函數內部(除非新的和刪除之間沒有代碼可以拋出)。

即使沒有代碼會拋出異常,當你寫的代碼,這可能在未來改變(所需要的是有人走過來,再添新後的第一個)。即使在例外情況下,仍然保持正確的編寫代碼更好。

選項1創建了很多代碼重複,很容易出錯,我甚至懷疑它可以稱之爲選項。

選項2會使safe_delete變得冗餘,因爲您設置爲0的ptr_將超出下一行的範圍。

概括 - 因爲它是不是在所有安全不使用SAFE_DELETE(這是非常困難的正確使用,並導致冗餘代碼,即使它的使用是正確的)。使用SBRM和智能指針。