setjmp / longjmp失败

时间:2012-06-21 13:54:03

标签: c setjmp

这里有一段代码

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跳回到前一个堆栈。但我不确定细节,以及'mark'中存储了什么样的价值,任何人都可以解释一下吗?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

你正试图重新回到更深层的功能。你只能长时间回到较浅的功能。

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

但如果A调用b,B调用setjmp,则B返回A,不能 longjmp返回B.

答案 2 :(得分:2)

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

  

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

     

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

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