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()場合、スタックフレームは無効になります。 (サブ関数はOKです)longjmp()と同じ関数で呼び出されることを意味します。setjmp()

于 2012-06-21T13:57:11.437 に答える
2

あなたはより深い機能にlongjmpして戻ろうとしています。longjmpで戻ることができるのは、より浅い関数だけです。

したがって、Aがsetjmpを呼び出してからBを呼び出すと、BはlongjmpAに戻ることができます。

しかし、Aがbを呼び出しsetjmp、Bが呼び出した場合、BはAに戻り、AはBに戻ることはできません longjmp

于 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 に答える