2010-08-15 128 views
5

我有一個關於內存釋放和異常的問題。當我使用刪除來刪除在堆上創建的對象時。如果在刪除之前發生異常,內存泄漏或將執行此刪除操作?內存釋放和異常

+0

你的意思是之前,而不是?那麼這很明顯,如果'delete'不會被調用(因爲之前拋出異常),那麼不會釋放內存。如果您在銷燬期間詢問異常,請http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3 – adf88 2010-08-15 09:09:26

回答

3

這取決於delete的位置。如果它在捕獲異常的catch內,則可能會調用它。

try { 
    f(); // throws 
} catch(...) { 
    delete p; // will delete 
} 

如果它是捕捉異常的catch後和catch不從函數返回(即允許執行流程的catch塊之後進行),那麼delete可能會被調用。

try { 
    f(); // throws 
} catch(...) { 
    // execution proceeds beyond catch 
} 
delete p; // will delete 

如果delete不處於catch塊或catch塊,其允許執行繼續進行,則delete不會調用之後。

try { 
    f(); // throws 
} catch(...) { 
    g(); // throws 
    delete p; // will not delete 
} 
+1

請注意,異常情況良好,因爲您不必每次都捕獲它們函數在調用堆棧中。它們可以在一個「外部」層面上連接。你如何釋放內部函數中分配的內存?例如,如果函數f()拋出一個異常分配內存。在f()和空閒內存中捕獲異常,然後在調用堆棧中將其重新拋入下一級,會不會是一個好主意? – NickSoft 2013-03-14 08:51:04

2

它不會被調用。這就是爲什麼你被鼓勵去看RAII的原因。請參閱Stroustrup

5

在您描述的情況下,內存將泄漏。

兩個技巧來避免這個問題:

  • 使用智能指針,不從相同的問題的困擾(優選溶液)
    - >在堆棧上構造的智能指針,其因此,調用析構函數,不管是什麼,並在析構函數提供

  • 使用try/catch語句所指向的內容刪除,並在catch語句刪除的項目以及

0

我們還必須確保「異常」:

try { 
    f(); // throws 
    delete p; // will not delete 
} // ... 

正如你可以想像,在兩個第一例delete上面不會,如果有是delete前一拋調用真的意味着可以被try/catch捕獲的C++異常。在C++ try/catch無法捕捉的系統中也存在其他異常(例如,除以0)。在這種情況下(超出C++標準的範圍),除非這些異常被捕獲並且處理程序明確地調用「delete」,否則「delete」將不會被執行。