C++中的栈展开

堆栈展开 在运行时从函数调用堆栈中删除函数项的过程。局部对象的销毁顺序与构造顺序相反。

null

堆栈展开通常与 异常处理 在C++中,当发生异常时,函数调用堆栈被线性搜索异常处理程序,并且在函数处理程序栈中移除具有异常处理程序的函数之前的所有条目。因此,如果一个异常没有在同一个函数(抛出异常的地方)中处理,那么异常处理涉及堆栈展开。基本上,堆栈展开是为运行时构造的所有自动对象调用析构函数(每当抛出异常时)的过程。

例如,以下程序的输出为:

CPP

// CPP Program to demonstrate Stack Unwinding
#include <iostream>
using namespace std;
// A sample function f1() that throws an int exception
void f1() throw ( int )
{
cout << " f1() Start " ;
throw 100;
cout << " f1() End " ;
}
// Another sample function f2() that calls f1()
void f2() throw ( int )
{
cout << " f2() Start " ;
f1();
cout << " f2() End " ;
}
// Another sample function f3() that calls f2() and handles
// exception thrown by f1()
void f3()
{
cout << " f3() Start " ;
try {
f2();
}
catch ( int i) {
cout << " Caught Exception: " << i;
}
cout << " f3() End" ;
}
// Driver Code
int main()
{
f3();
getchar ();
return 0;
}


输出

 f3() Start 
 f2() Start 
 f1() Start 
 Caught Exception: 100
 f3() End

说明:

  • 当f1()抛出异常时,它的条目将从函数调用堆栈中删除,因为f1()不包含抛出异常的异常处理程序,所以调用堆栈中的下一个条目将查找异常处理程序。
  • 下一个条目是f2()。由于f2()也没有处理程序,因此它的条目也会从函数调用堆栈中删除。
  • 函数调用堆栈中的下一个条目是f3()。由于f3()包含异常处理程序,因此会执行f3()内的catch块,最后执行catch块后的代码。

请注意,f1()和f2()中的以下行根本不执行。

 cout<<" f1() End ";  // inside f1()

 cout<<" f2() End ";  // inside f2()

如果f1()和f2()中有一些本地类对象,那么这些本地对象的析构函数将在堆栈展开过程中被调用。

注: 在Java中,当异常未在同一个函数中处理时,堆栈展开也会发生。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享