Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
exit() / atexit() / abort()
プログラムを終了させる関数です。正常終了・エラー終了・強制終了の3種類があり、用途によって使い分けます。
構文
// プログラムを正常に終了します。atexit 登録関数・バッファのフラッシュ・一時ファイルの削除が行われます。 // status: EXIT_SUCCESS(0) または EXIT_FAILURE(1) を渡します。 void exit(int status); // exit() 呼び出し時に実行する関数を登録します(最大32個以上)。 // 登録した逆順(LIFO)で呼ばれます。 // 戻り値: 成功時は 0、失敗時は非0。 int atexit(void (*func)(void)); // プログラムを異常終了します。atexit 関数・バッファフラッシュは行われません。 // SIGABRT シグナルを発生させてコアダンプを生成します。 void abort(void); // プログラムをすぐに終了します。exit() と違い後処理を一切行いません。 void _Exit(int status); // C99以降
終了関数の比較
| 関数 | atexit実行 | バッファFlush | 用途 |
|---|---|---|---|
| exit() | あり | あり | 通常の正常・エラー終了です。 |
| _Exit() | なし | なし | 後処理なしで即時終了します。フォークした子プロセスの終了などに使います。 |
| abort() | なし | なし | 回復不能なエラー時に異常終了します。assert() もこれを呼びます。 |
| return(main) | あり | あり | main() からのreturnはexit()と同等です。推奨されます。 |
サンプルコード
#include <stdio.h>
#include <stdlib.h>
// atexit に登録するクリーンアップ関数です。
void cleanup_a(void) { printf("cleanup_a: 一時ファイルを削除しました。\n"); }
void cleanup_b(void) { printf("cleanup_b: ログを閉じました。\n"); }
int main(void) {
// atexit でクリーンアップ関数を登録します(逆順で呼ばれます)。
atexit(cleanup_a);
atexit(cleanup_b); // cleanup_b → cleanup_a の順に呼ばれます。
printf("処理を開始します。\n");
// ファイルオープン失敗など回復不能なエラーの場合に exit します。
FILE *fp = fopen("config.txt", "r");
if (fp == NULL) {
fprintf(stderr, "設定ファイルが見つかりません。\n");
exit(EXIT_FAILURE); // atexit 登録関数が呼ばれてから終了します。
}
// このサンプルでは fopen が失敗して exit() が呼ばれます。
fclose(fp);
return EXIT_SUCCESS;
}
概要
main() から return するのと exit(status) を呼ぶのは同等の動作です。main() 以外の深い関数から一気に終了したい場合にのみ exit() を使い、通常は return を使う方がコードの流れが追いやすくなります。
atexit() に登録した関数は exit() のときのみ呼ばれます。abort() やシグナルによる強制終了では呼ばれないことに注意してください。オープンしたファイルは exit() 時に自動でフラッシュ・クローズされますが、動的に確保したメモリは解放されずに終了します(OS がプロセス終了時に回収します)。
プログラムの状態チェックには『assert()』も参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。