2017-01-19 40 views
1

當使用new並引發bad_alloc異常時。在繼續之前,你還需要在ptr上調用delete嗎?還是可以確信沒有分配內存?關於new的錯誤分配錯誤,還需要調用delete嗎?

如果您使用nothrow版本,那麼如何?如果返回nullptr,你能再次確信沒有分配內存嗎?

+0

你在說什麼「ptr」?發佈一些代碼。 –

+0

任何正在通過新的 –

+0

後分配內存的ptr。一些。碼。問題的第一部分是書面的無法回答的,邊緣的荒謬。當「新」拋出時,表達式評估沒有完成。 –

回答

2

當一個異常被拋出,你不「矣」 - 執行跳轉到catch處理。

在像的表達式:

p = new int; 

子表達式new int首先計算。如果拋出一個異常,那麼執行沒有達到分配。 p保留之前的值(如果有的話)。

p = new(std::nothrow) int;的情況下,如果分配失敗,p將變爲空指針。在空指針上調用delete不起作用。

+0

沒有它沒有。你回答了。我問你是否可以確信沒有任何分配和/或沒有分配內存。 –

2

new的拋出異常的版本確實通過返回一個空指針,在這種情況下,沒有內存的分配報告錯誤和沒有對象已建成:

T * p = new (std::nothrow) T(a, b, c); 

if (p) 
{ 
    // stuff 
} 

delete p; // OK, works on null pointers, too. 

或許:

if (T * p = new (std::nothrow) T(a, b, c)) 
{ 
    // stuff 
    delete p; 
} 
else 
{ 
    // allocation failure 
} 

或甚至更好:

if (std::unique_ptr<T> p(new (std::nothrow) T(a, b, c))) 
{ 
    // stuff 
} 

最後一個版本自動刪除在if區塊的任何退出時出現的動態對象,這是C++處理多個出口並因此定位複雜性的典型示例。

(也許應該有一個make_unique_or_null函數模板來封裝這最後一點。)

+1

當然,第二個例子有內存泄漏的問題,如果// stuff可以拋出 –

+0

@ M.M:第一個例子也有這個問題。我假設你通常知道需要異常正確的代碼。 –

+1

是的,我認爲如果你的回答在某個階段提到這將是一件好事,因爲初學者並不清楚最後一個版本的優點是什麼 –