異常棧展開和對象析構

來源:互聯網
上載者:User
1、函數調用鏈

函數與子函數之間的調用關係可以用一個鏈來表示,調用連,相關的一個重要資料結構就是棧幀,子函數返回的時候,棧展開,構造在棧上的對象被編譯器設定的解構函式析構銷毀。

 函數調用         A ----------------------> B ---------------------> C ------------------------->D

2、異常處理鏈

類似的,windows上的結構化異常處理也有一個類似的異常處理鏈,而且這個鏈剛好也是在棧上構造的,但是和函數正常的鏈是各自獨立的。當某一個子函數發生異常的時候,就不能走正常的調用連返回,進而析構對象;這個時候,需要走異常鏈來回溯,展開異常調用鏈,所有附著在異常鏈上的對象,在異常鏈的第二次調用(unwind處理,第一次是搜尋異常處理者)的時候析構。

異常鏈       ExcpNode_A-------> ExcpNode_B------------------------------------------->!!BOMB!!<

每一個節點都包含了該函數對應的對象的析構操作,正常調用鏈也好,異常鏈也好,都是這樣的,這些是由C++編譯器完成的。每一個call操作,c++編譯器產生一個子函數棧幀節點。每一個try-catch語句,c++語句構造一個異常鏈節點。

但是,如果一個程式員在C函數裡面沒有寫try-catch,但是D函數裡面有try-catch語句,而且啟動並執行時候,在D函數裡面發生了異常,那麼C函數裡面的產生的所有對象得不到析構的機會。

3、測試程式碼

// debugee.cpp : Defines the entry point for the console application.//#include "stdafx.h"class Object{public:Object(const char tag) : m_tag(tag){printf("Object [%c] %p\n", m_tag, this);};~Object(){printf("~Object [%c] %p\n", m_tag, this);};private:char m_tag;};void D(void){Object d('D');*(int *)0 = 0;}void C(void){Object c('C');D();}void B(void){Object b('B');try{C();}catch(...){printf("B caught exception.\n");}}void A(void){Object a('A');try{B();}catch(...){printf("A caught exception.\n");}}int main(int argc, char* argv[]){A();return 0;}

4、輸出:

5、注意編譯器實現差異

vc編譯器的版本差異和編譯選項的差異,vc2005的/EHsc標記。

class Object{public:    Object(const char tag) : m_tag(tag)    {printf("Object [%c] %p\n", m_tag, this);};    ~Object()    {printf("~Object [%c] %p\n", m_tag, this);};private:    char m_tag;};void E(void){    Object e('E');    //try    {        throw("");    }    //catch (...)    {    }}void D(void){    Object d('D');    E();}void C(void){    Object c('C');    D();}void B(void){    Object b('B');    //try    {        C();    }    //catch(...)    {        printf("B caught exception.\n");    }}void A(void){    Object a('A');    try    {        B();    }catch(...)    {        printf("A caught exception.\n");    }}int main(int argc, char* argv[]){    A();    return 0;}

不帶/EHsc產生的結果符合預期

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.