拋出異常與棧展開(stack unwinding)


拋出異常時,將暫停當前函數的執行,開始查找匹配的catch子句。首先檢查throw本身是否在try塊內部,如果是,檢查與該try相關的catch子句,看是否可以處理該異常。如果不能處理,就退出當前函數,並且釋放當前函數的內存並銷毀局部對象,繼續到上層的調用函數中查找,直到找到一個可以處理該異常的catch。這個過程稱為棧展開(stack unwinding)。當處理該異常的catch結束之后,緊接着該catch之后的點繼續執行。

1. 為局部對象調用析構函數

如上所述,在棧展開的過程中,會釋放局部對象所占用的內存並運行類類型局部對象的析構函數。但需要注意的是,如果一個塊通過new動態分配內存,並且在釋放該資源之前發生異常,該塊因異常而退出,那么在棧展開期間不會釋放該資源,編譯器不會刪除該指針,這樣就會造成內存泄露。

2. 析構函數應該從不拋出異常

在為某個異常進行棧展開的時候,析構函數如果又拋出自己的未經處理的另一個異常,將會導致調用標准庫terminate函數。通常terminate函數將調用abort函數,導致程序的非正常退出。所以析構函數應該從不拋出異常。

3. 異常與構造函數

如果在構造函數對象時發生異常,此時該對象可能只是被部分構造,要保證能夠適當的撤銷這些已構造的成員。

4. 未捕獲的異常將會終止程序

不能不處理異常。如果找不到匹配的catch,程序就會調用庫函數terminate。

【學習資料】 《c++ primer》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM