C++中的栈展开介绍和示例解析

2021年3月16日16:38:07 发表评论 1,007 次浏览

在运行时从函数调用栈中删除函数条目的过程称为栈展开。栈展开通常与异常处理有关。在C ++中, 当发生异常时, 将在函数调用栈中线性搜索异常处理程序, 并将带有异常处理程序的函数之前的所有条目从函数调用栈中删除。因此, 如果未在同一函数中(抛出异常的地方)处理异常, 则异常处理涉及栈展开。

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

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

在上述程序中, 当f1()引发异常时, 其条目从函数调用栈中删除(因为f1()不包含所引发异常的异常处理程序), 然后在调用栈中查找下一个条目以查找异常处理程序。下一个条目是f2()。由于f2()也没有处理程序, 因此其条目也会从函数调用栈中删除。函数调用栈中的下一个条目是f3()。由于f3()包含异常处理程序, 因此将执行f3()内部的catch块, 最后执行catch块之后的代码。请注意, 根本不执行f1()和f2()内部的以下行。

//inside f1()
   cout<< "\n f1() End " ; 
  
//inside f2()
   cout<< "\n f2() End " ;

附带说明一下, 如果f1()和f2()内有一些本地类对象, 则在栈展开过程中将调用这些本地对象的析构函数。

如果未在同一函数中处理异常, 则Java中也会发生栈展开。

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

被认为是行业中最受欢迎的技能之一, 我们拥有自己的编码基础C++ STL通过激烈的问题解决过程来训练和掌握这些概念。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: