2011-07-20 98 views
0

可能重複:
Is it safe to delete a NULL pointer?刪除未初始化對象在C++

以我的頭文件我聲明類的範圍內的變量:

FaultModel<double> *fm_req_set_odom_px; 

。 ..在類構造函數中有條件地初始化,具體取決於配置文件的值:

const char *configModel = ConfigReader->ReadString("FaultModel"); 
    if (strcmp(configModel, "cyclic") == 0) 
     fm_req_set_odom_px = new CyclicFaultModel<double>(); 

我的問題是:我需要換一個有條件的刪除檢查,如果模型初始化或者沒有,或者它安全刪除它在任何情況下?

if (fm_req_set_odom_px != NULL) // Is this necessary? 
     delete fm_req_set_odom_px; 
+0

@Kerrek SB,您可以更多地瞭解管理容器的資源。並不是每個人都已經熟悉C++ 11,並且使用Google搜索這並不能真正給出結果 – KillianDS

+1

@KillianDS:他們與C++ 0x無關;智能指針和容器已經成爲C++庫的一部分,因爲在有標準之前,使用它們的建議不是試圖手動管理資源(這總是容易出錯,並且在出現異常時通常是不可能的)在過去的十年或兩年內普遍存在。 –

+0

好吧,對我而言,你的意思並不清楚,你的意思是聰明的指針等等)。 – KillianDS

回答

5

delete NULL;保證是無操作的,所以手動檢查是沒有必要的。然而,未初始化的指針變量不NULL,所以你必須,如果條件不滿足明確設置爲NULL

if (strcmp(configModel, "cyclic") == 0) 
    fm_req_set_odom_px = new CyclicFaultModel<double>(); 
else 
    fm_req_set_odom_px = NULL; 

或者,你可以在if語句之前無條件設置指針變量NULL

fm_req_set_odom_px = NULL; 
if (strcmp(configModel, "cyclic") == 0) 
    fm_req_set_odom_px = new CyclicFaultModel<double>(); 
+4

雖然OP從未說過她將指針初始化爲0,但這是她代碼中更明顯的缺陷。 –

+2

恕我直言,你應該使用C++ 0x nullptr,NULL宏不再時髦:) - 編輯,Kerrek的評論是有效的,如果指針未初始化爲nullptr它不安全刪除它。 –

+0

我可以在Kerrek SB上說的不止一次投票... –

0

通常情況下,您會改爲使用諸如boost::variant之類的東西來保持可能性。在這種情況下,基於堆的動態分配是浪費的。 boost::variant將永遠適當地銷燬你的內容,你將不必擔心編寫自己的拷貝構造函數/賦值操作符。

+1

boost ::可選。 - 我無法想到在這種特殊情況下提供boost :: variant而不是boost :: optional的相關原因 – sehe

1

沒有必要檢查。但更好的方法是使用智能指針...

+2

您認爲使用'delete'和空指針會有什麼危害嗎?因爲它不。 –

+0

我不會刪除我的答案,因爲我清楚地說使用智能指針是更好的方法,但我支持檢查... – Nim

+1

該檢查沒有什麼壞處,只是膨脹了源代碼。你所說的是,「刪除前你應該經常檢查」。即使這張支票根本沒有任何傷害,但它沒有任何好處,所以我不明白爲什麼每個人都應該這樣做。 –

0
delete NULL; 

沒有任何影響,所以測試是沒有必要的。

+0

但如果指針永遠不會初始化爲0或NULL,那該怎麼辦? –

+0

@CJ:'刪除NULL;'總是沒有效果。 NULL始終爲NULL - 沒有指向初始化的指針。 'delete p;'p'未初始化的地方是UB。 – qbert220

0

delete檢查NULL,不需要if (myVar != NULL) delete myVar;。另外,請考慮使用std::auto_ptr(或其他智能指針容器)。這可以讓您擺脫很多麻煩,例如未初始化的指針。

從中適當地指導你其他的答案
6

除此之外,

如果MUST使用動態分配的對象則不要使用原始指針但使用智能指針

總是利用RAII(SBRM)它使您的生活更輕鬆。 這樣你不必費心明確刪除任何資源,資源本身會照顧它

0

我認爲首先要問的一個更基本的問題是:你是否在構造函數中初始化指針爲NULL? (即例如使用初始化器列表)。

如果您沒有將它初始化爲NULL,那麼當您嘗試刪除隨機存儲器位時,您很可能會遇到訪問衝突。 如果您將它初始化爲NULL,那麼您可以跳過if guard語句。