CおよびC++では、exit()
とabort()
の違いは何ですか?エラー(例外ではない)の後にプログラムを終了しようとしています。
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);
を代わりに配置します。
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
プログラムがexit
()を呼び出すと、次のことが起こります。
atexit
関数によって登録された関数が実行されますtmpfile
によって作成されたファイルは削除されますabort
()関数は、SIGABRT
シグナルを現在のプロセスに送信します。キャッチされない場合、開いているストリームがフラッシュ/クローズされること、またはtmpfile
は削除され、atexit
登録済み関数は呼び出されず、ゼロ以外の終了ステータスがホストに返されます。
Exit()マニュアルページから:
Exit()関数により、プロセスが正常に終了し、ステータス&0377の値が親に返されます。
Abort()マニュアルページから:
Abort()は最初にSIGABRTシグナルのブロックを解除してから、呼び出しプロセスのシグナルを発生させます。これにより、SIGABRTシグナルがキャッチされ、シグナルハンドラが返されない限り、プロセスは異常終了します。
abort
はSIGABRT
信号を送信します。 abort
は呼び出し元に戻りません。 SIGABRT
信号のデフォルトのハンドラーは、アプリケーションを閉じます。 stdio
ファイルストリームはフラッシュされ、閉じられます。ただし、C++クラスインスタンスのデストラクタはそうではありません(これについてはわかりません。おそらく結果は未定義ですか?)。
exit
には、atexit
で設定される独自のコールバックがあります。コールバックが指定されている(または1つのみ)場合、それらは登録順序と逆の順序(スタックなど)で呼び出され、プログラムは終了します。 abort
と同様に、exit
は呼び出し元に戻りません。 stdio
ファイルストリームはフラッシュされ、閉じられます。また、C++クラスインスタンスのデストラクタが呼び出されます。