0

一段代码在这里

jmp_buf mark;
int Sub_Func()  
{  
    int be_modify, jmpret;    
    be_modify = 0;    
    jmpret = setjmp( mark );  
    if( jmpret == 0 )  
    {  
        // sth else here 
    }  
    else  
    {  
        // error handle 
        switch (jmpret)  
        {  
            case 1:  
                printf( "Error 1\n");  
                break;  
            case 2:  
                printf( "Error 2\n");  
                break;  
            case 3:  
                printf( "Error 3\n");  
                break;  
            default :  
                printf( "Unknown Error");  
                break;  
        }  
        printf("after switch\n");        
    }     
    return jmpret;  
}  

void main( void )  
{  
    Sub_Func();   
    // the longjmp after setjmp
    longjmp(mark, 1);  
}  

结果是: 切换 分段故障 后出现
错误1

我知道可能 longjmp 跳回前一个堆栈的原因。但我不确定细节,“标记”中存储了什么样的值,谁能解释一下?

4

3 回答 3

3

setjmp()longjmp()通过记录堆栈帧位置来工作。如果您Sub_Func()在调用之前记录了堆栈帧但从函数返回longjmp(),则堆栈帧不再有效。 意味着在与(子函数正常)longjmp()相同的函数中调用。setjmp()

于 2012-06-21T13:57:11.437 回答
2

您正试图 longjmp 回到更深层次的功能。您只能 longjmp 回到较浅的函数。

因此,如果 A 调用setjmp,然后调用 B,则 B 可以longjmp返回 A。

但是如果A调用b,B调用setjmp,B返回A,A不能 longjmp返回B。

于 2012-06-21T13:59:03.440 回答
2

您通过违反以下 (7.13.2.1) 调用了未定义的行为:

longjmp 函数使用相应的 jmp_buf 参数恢复由最近调用 setjmp 宏在程序的同一调用中保存的环境。如果没有这样的调用,或者如果包含 setjmp 宏调用的函数在此期间终止了执行 217),或者如果 setjmp 宏的调用在具有可变修改类型的标识符的范围内并且执行已经离开在此范围内,行为未定义。

217) 例如,通过执行 return 语句或因为另一个 longjmp 调用已导致转移到嵌套调用集中较早的函数中的 setjmp 调用。

简而言之,longjmp不能用于跳转到setjmp函数中已经返回的点。

于 2012-06-21T14:15:42.747 回答