丟擲異常時,將暫停當前函式的執行,開始查詢匹配的catch子句。首先檢查throw本身是否在try塊內部,如果是,檢查與該try相關的catch子句,看是否可以處理該異常。如果不能處理,就退出當前函式,並且釋放當前函式的記憶體並銷毀區域性物件,繼續到上層的呼叫函式中查詢,直到找到乙個可以處理該異常的catch。這個過程稱為棧展開(stack unwinding)。當處理該異常的catch結束之後,緊接著該catch之後的點繼續執行。
1. 為區域性物件呼叫析構函式
如上所述,在棧展開的過程中,會釋放區域性物件所占用的記憶體並執行類型別區域性物件的析構函式。但需要注意的是,如果乙個塊通過new動態分配記憶體,並且在釋放該資源之前發生異常,該塊因異常而退出,那麼在棧展開期間不會釋放該資源,編譯器不會刪除該指標,這樣就會造成記憶體洩露。
2. 析構函式應該從不丟擲異常
在為某個異常進行棧展開的時候,析構函式如果又丟擲自己的未經處理的另乙個異常,將會導致呼叫標準庫terminate()函式。通常terminate()函式將呼叫abort()函式,導致程式的非正常退出。所以析構函式應該從不丟擲異常。
3. 異常與建構函式
如果在建構函式物件時發生異常,此時該物件可能只是被部分構造,要保證能夠適當的撤銷這些已構造的成員。
4. 未捕獲的異常將會終止程式
不能不處理異常。如果找不到匹配的catch,程式就會呼叫庫函式terminate().
注:筆者加一段**以說明
#include #include using namespace std;
void func ()
catch (...)
*p = 20;
cout << *p << endl; // 20
}int main()
(完) 丟擲異常與棧展開(stack unwinding)
丟擲異常時,將暫停當前函式的執行,開始查詢匹配的catch子句。首先檢查throw本身是否在try塊內部,如果是,檢查與該try相關的catch子句,看是否可以處理該異常。如果不能處理,就退出當前函式,並且釋放當前函式的記憶體並銷毀區域性物件,繼續到上層的呼叫函式中查詢,直到找到乙個可以處理該異常的...
丟擲異常與棧展開(stack unwinding)
1.為區域性物件呼叫析構函式 如上所述,在棧展開的過程中,會釋放區域性物件所占用的記憶體並執行類型別區域性物件的析構函式。但需要注意的是,如果乙個塊通過new動態分配記憶體,並且在釋放該資源之前發生異常,該塊因異常而退出,那麼在棧展開期間不會釋放該資源,編譯器不會刪除該指標,這樣就會造成記憶體洩露。...
丟擲異常與棧展開(stack unwinding)
丟擲異常時,將暫停當前函式的執行,開始查詢匹配的catch子句。首先檢查throw本身是否在try塊內部,如果是,檢查與該try相關的catch子句,看是否可以處理該異常。如果不能處理,就退出當前函式,並且釋放當前函式的記憶體並銷毀區域性物件,繼續到上層的呼叫函式中查詢,直到找到乙個可以處理該異常的...