什么是栈展开?搜索了一遍,但没有找到有启发性的答案!
当前回答
在一般意义上,堆栈“unwind”几乎等同于函数调用的结束和随后的堆栈弹出。
然而,特别是在c++的情况下,堆栈展开必须与c++如何调用自任何代码块开始分配的对象的析构函数有关。在块中创建的对象将按照其分配的相反顺序被释放。
其他回答
堆栈展开是在运行时从函数调用堆栈中删除函数项的过程。它通常与异常处理有关。在c++中,当发生异常时,函数调用堆栈会线性地搜索异常处理程序,在带有异常处理程序的函数之前的所有条目都将从函数调用堆栈中删除。
堆栈展开主要是c++的概念,处理当堆栈分配的对象的作用域退出时(正常退出或通过异常退出)如何销毁。
假设你有这样一段代码:
void hw() {
string hello("Hello, ");
string world("world!\n");
cout << hello << world;
} // at this point, "world" is destroyed, followed by "hello"
在一般意义上,堆栈“unwind”几乎等同于函数调用的结束和随后的堆栈弹出。
然而,特别是在c++的情况下,堆栈展开必须与c++如何调用自任何代码块开始分配的对象的析构函数有关。在块中创建的对象将按照其分配的相反顺序被释放。
在我看来,本文中给出的下图漂亮地解释了堆栈unwind对下一条指令路径的影响(一旦抛出未捕获的异常,将执行):
在图片中:
上面一个是正常的调用执行(没有抛出异常)。 当抛出异常时,位于底部。
在第二种情况下,当发生异常时,将在函数调用堆栈中线性搜索异常处理程序。搜索结束于带有异常处理程序的函数,即带有try-catch块的main(),但不是在从函数调用堆栈中删除它之前的所有条目之前。
每个人都谈论过c++中的异常处理。但是,我认为堆栈展开还有另一个内涵,它与调试有关。调试器必须在应该转到当前帧之前的帧时进行堆栈展开。然而,这是一种虚拟unwind,因为当它回到当前帧时需要倒带。例如gdb中的up/down/bt命令。
推荐文章
- Linux有c++ gdb图形用户界面吗?
- 从标准输入中捕获字符,而不需要等待按enter键
- libpng警告:iCCP:已知错误的sRGB配置文件
- 为什么STL如此严重地基于模板而不是继承?
- 查找当前可执行文件的路径,不包含/proc/self/exe
- 未定义对静态constexpr char的引用[]
- 在c++中,restrict关键字是什么意思?
- c++中类似于java的instanceof
- include_directories和target_include_directories在CMake中的区别是什么?
- std::make_pair与std::pair的构造函数的目的是什么?
- 如何追加一个字符到std::字符串?
- 为什么要在c++中使用嵌套类?
- 如何处理11000行c++源文件?
- 使用g++编译多个.cpp和.h文件
- 如何在c++中追加文本到文本文件?