总觉得setjmp和longjmp会破坏堆栈,它究竟是如何能正确执行的?

numddd 2011-07-12 01:21:05
longjmp的时候,跳转到别处: 问题是,编译器并不能预知,longjmp的时候,堆栈上到底有多少东西了,如果setjmp的地方是一个初始化的地方,岂不是造成堆栈上被跳过的那些对象/指针/资源没有被释放

而且从这个函数跳转到那个函数,longjmp出发的函数没有退栈,longjmp进入的函数栈顶/栈底指针和初次调用相比已经发生了变化,总觉得这会让程序崩溃啊.

它究竟是如何能正确执行的呢? 高手指点一下!
...全文
218 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2011-07-12
  • 打赏
  • 举报
回复
如果有 delete 或者析构函数这些被跳过, 那是程序自己的问题, 这个函数本来就是 C 的. 除了栈内存外的资源的释放你得自己处理.
而对于栈内存本身来说, 其实只是一个堆栈指针 ESP 的变化, 并没有真正的内存申请释放操作.
至于进入函数, 退出函数这些操作其实都是在加减 ESP. setjmp 直接保存了 ESP, 而 longjmp 直接把保存的 ESP 值恢复. 所以不管你从哪里跳回去, 堆栈指针都是你第一次调用 setjmp 那个样子, 保证堆栈是平衡的, 不会崩溃.
luciferisnotsatan 2011-07-12
  • 打赏
  • 举报
回复
反汇编,看看怎么做的

longjmp这种跳转方式,本来就不建议使用
至善者善之敌 2011-07-12
  • 打赏
  • 举报
回复
殊不知,经常有程序乱飞,WINDOWS会提示越界
赵4老师 2011-07-12
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <setjmp.h>
jmp_buf mark;
int i=0;
void c() {
printf( "c in\n");
if (1==i%2) longjmp( mark, i );
printf( "c out\n");
}
void b() {
printf( "b in\n");
c();
printf( "b out\n");
}
void a() {
printf( "a in\n");
b();
printf( "a out\n");
}
void main( void )
{
int jmpret;
jmpret = setjmp( mark );
printf( "Start %d\n",jmpret);
if( jmpret == 0 ) {
printf( "First\n");
a();
i++;
a();
} else {
printf( "Second\n");
}
}
//Start 0
//First
//a in
//b in
//c in
//c out
//b out
//a out
//a in
//b in
//c in
//Start 1
//Second
//
赵4老师 2011-07-12
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编并单步执行。)
healer_kx 2011-07-12
  • 打赏
  • 举报
回复
不乱跳就没事。

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧