棧展開

棧展開(stack unwinding)是指,如果在一個函式內部拋出異常,而此異常並未在該函式內部被捕捉,就將導致該函式的運行在拋出異常處結束,所有已經分配在棧上的局部變數都要被釋放。

基本介紹

  • 中文名:棧展開
  • 外文名:stack unwinding
  • 所屬領域:計算機編程
帶來的危害,記憶體泄露,

帶來的危害

在棧展開的過程中,如果被釋放的局部變數中有指針,而該指針在此前已經用new運算申請了空間,就有可能導致記憶體泄露。因為棧展開的時候並不會自動對指針變數執行delete(或delete[])操作。

記憶體泄露

因此,在有可能發生異常的函式中,在C++編程中,可以利用“智慧型指針”auto_ptr來防止記憶體泄露。參考如下程式。
#include <iostream>#include <memory>using namespace std; class A{    int num;public:    A(int i):num(i){        cout<<"this is A's constructor, num="<<num<<endl;    }    ~A(){        cout<<"this is A's destructor, num="<<num<<endl;    }    void show(){        cout<<num<<endl;    }}; void autoptrtest1(){    A* pa=new A(1);    throw 1;    delete pa;} void autoptrtest2(){    auto_ptr<A> pa(new A(2));    pa->show();    throw 2;} int main(){    try{        autoptrtest1();    }      catch(int){        cout<<"there is no destructor invoked"<<endl;    }    cout<<endl;    try{        autoptrtest2();    }    catch(int){        cout<<"A's destructor does be invoked"<<endl;    }}                 程式的輸出結果:this is A's constructor, num=1there is no destructor invoked this is A's constructor, num=22this is A's destructor, num=2A's destructor does be invoked
在解讀上面的這段程式的時候,要注意以下幾點。
(1)在函式autoptrtest1()中,由於異常的發生,導致delete pa;無法執行,從而導致記憶體泄露。
(2)auto_ptr實際上是一個類模板,在名稱空間std中定義。要使用該類模板,必須包含頭檔案memory。auto_ptr的構造函式可以接受任何類型的指針,實際上是利用指針類型將該類模板實例化,並將傳入的指針保存在auto_ptr<T>對象中。
(3)在棧展開的過程中,auto_ptr<T>對象會被釋放,從而導致auto_ptr<T>對象的析構函式被調用。在該析構函式中,將使用delete運算符將保存在該對象內的指針所指向的動態對象被銷毀。這樣,就不會發生記憶體泄露了。
(4)由於已經對*和->操作符進行了重載,所以可以像使用普通的指針變數那樣使用auto_ptr<T>對象,如上面程式中的pa->show()。這樣可以保留使用指針的編程習慣,方便程式猿編寫和維護。

相關詞條

熱門詞條

聯絡我們