-
棧展開
鎖定
棧展開(stack unwinding)是指,如果在一個函數內部拋出異常,而此異常並未在該函數內部被捕捉,就將導致該函數的運行在拋出異常處結束,所有已經分配在棧上的局部變量都要被釋放。
[1]
- 中文名
- 棧展開
- 外文名
- stack unwinding
- 所屬學科
- 計算機
- 所屬領域
- 計算機編程
棧展開帶來的危害
棧展開內存泄露
因此,在有可能發生異常的函數中,在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=1 there is no destructor invoked this is A's constructor, num=2 2 this is A's destructor, num=2 A'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)。這樣可以保留使用指針的編程習慣,方便程序猿編寫和維護。