CおよびC ++では、違いは何であるexit()
とはabort()
?エラー(例外ではない)の後でプログラムを終了しようとしています。
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は静的メンバーとグローバルメンバーのオブジェクト破棄を実行しませんが、終了します。
もちろん、アプリケーションが完全に閉じられると、オペレーティングシステムは解放されていないメモリやその他のリソースを解放します。
(デフォルトの動作をオーバーライドしなかったと仮定して)アボートプログラムと終了プログラムの両方の終了で、戻りコードは、アプリケーションを開始した親プロセスに返されます。
次の例を参照してください。
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;
}
コメント:
中止がコメント化されていない場合:何も出力されず、someobjectのデストラクタは呼び出されません。
もし アボートは、上記のようにコメントしている:SomeObjectのデストラクタを使用すると、次のような出力が得られます呼び出されます。
出口機能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 ++クラスインスタンスのデストラクタが呼び出されます。