web-dev-qa-db-ja.com

exit()とabort()の違いは何ですか?

CおよびC++では、exit()abort()の違いは何ですか?エラー(例外ではない)の後にプログラムを終了しようとしています。

126
Nathan Stoddard

abort() 最初に atexit() を使用して登録された関数を呼び出さずに、オブジェクトのデストラクタを最初に呼び出さずにプログラムを終了します。 exit() は、プログラムを終了する前に両方を行います。ただし、自動オブジェクトのデストラクタは呼び出しません。そう

_A a;
void test() { 
    static A b;
    A c;
    exit(0);
}
_

aおよびbを適切に破棄しますが、cのデストラクターを呼び出しません。 abort()は、どちらのオブジェクトのデストラクターも呼び出しません。これは残念なことなので、C++標準では、適切な終了を保証する代替メカニズムについて説明しています。

自動保存期間を持つオブジェクトは、関数main()に自動オブジェクトが含まれず、exit()の呼び出しを実行するプログラムですべて破棄されます。 main()でキャッチされた例外をスローすることにより、そのようなmain()に直接制御を転送できます。

_struct exit_exception { 
   int c; 
   exit_exception(int c):c(c) { } 
};

int main() {
    try {
        // put all code in here
    } catch(exit_exception& e) {
        exit(e.c);
    }
}
_

exit()を呼び出す代わりに、そのコードthrow exit_exception(exit_code);を代わりに配置します。

113

abort SIGABRTシグナルを送信します。exitは、通常のクリーンアップを実行しているアプリケーションを閉じます。

abortシグナルは必要に応じて処理できますが、デフォルトの動作では、アプリケーションもエラーコードで閉じます。

abortは静的およびグローバルメンバーのオブジェクト破棄を実行しませんが、exitは実行します。

もちろん、アプリケーションが完全に閉じられると、オペレーティングシステムは解放されていないメモリやその他のリソースを解放します。

abortおよびexitの両方のプログラム終了(デフォルトの動作をオーバーライドしなかったと仮定)で、アプリケーションを開始した親プロセスに戻りコードが返されます。

次の例を参照してください。

SomeClassType someobject;

void myProgramIsTerminating1(void)
{
  cout<<"exit function 1"<<endl;
}

void myProgramIsTerminating2(void)
{
  cout<<"exit function 2"<<endl;
}

int main(int argc, char**argv)
{
  atexit (myProgramIsTerminating1);
  atexit (myProgramIsTerminating2);
  //abort();
  return 0;
}

コメント:

  • abortのコメントが外されている場合:何も出力されず、someobjectのデストラクタは呼び出されません。

  • abortが上記のようにコメントされている場合:someobject destructorが呼び出され、次の出力が得られます:

出口機能2
終了関数1

32
Brian R. Bondy

プログラムがexit()を呼び出すと、次のことが起こります。

  • atexit関数によって登録された関数が実行されます
  • 開いているストリームはすべてフラッシュされて閉じられ、tmpfileによって作成されたファイルは削除されます
  • プログラムは、ホストへの指定された終了コードで終了します

abort()関数は、SIGABRTシグナルを現在のプロセスに送信します。キャッチされない場合、開いているストリームがフラッシュ/クローズされること、またはtmpfileは削除され、atexit登録済み関数は呼び出されず、ゼロ以外の終了ステータスがホストに返されます。

10
Robert Gamble

Exit()マニュアルページから:

Exit()関数により、プロセスが正常に終了し、ステータス&0377の値が親に返されます。

Abort()マニュアルページから:

Abort()は最初にSIGABRTシグナルのブロックを解除してから、呼び出しプロセスのシグナルを発生させます。これにより、SIGABRTシグナルがキャッチされ、シグナルハンドラが返されない限り、プロセスは異常終了します。

5

abortSIGABRT信号を送信します。 abortは呼び出し元に戻りません。 SIGABRT信号のデフォルトのハンドラーは、アプリケーションを閉じます。 stdioファイルストリームはフラッシュされ、閉じられます。ただし、C++クラスインスタンスのデストラクタはそうではありません(これについてはわかりません。おそらく結果は未定義ですか?)。

exitには、atexitで設定される独自のコールバックがあります。コールバックが指定されている(または1つのみ)場合、それらは登録順序と逆の順序(スタックなど)で呼び出され、プログラムは終了します。 abortと同様に、exitは呼び出し元に戻りません。 stdioファイルストリームはフラッシュされ、閉じられます。また、C++クラスインスタンスのデストラクタが呼び出されます。

4
strager