exit() / atexit() / abort()
Functions for terminating a program. There are three types — normal termination, error termination, and forced termination — and you choose the right one depending on the situation.
Syntax
// Terminates the program normally. Runs atexit-registered functions, flushes buffers, and removes temporary files. // status: pass EXIT_SUCCESS(0) or EXIT_FAILURE(1). void exit(int status); // Registers a function to be called when exit() is invoked (at least 32 functions can be registered). // Registered functions are called in reverse order (LIFO). // Return value: 0 on success, non-zero on failure. int atexit(void (*func)(void)); // Terminates the program abnormally. Does not run atexit functions or flush buffers. // Raises the SIGABRT signal and generates a core dump. void abort(void); // Terminates the program immediately. Unlike exit(), performs no cleanup at all. void _Exit(int status); // C99 and later
Comparison of Termination Functions
| Function | Runs atexit | Flushes Buffers | Use Case |
|---|---|---|---|
| exit() | Yes | Yes | Standard normal or error termination. |
| _Exit() | No | No | Immediate exit with no cleanup. Useful for terminating a forked child process. |
| abort() | No | No | Abnormal termination on unrecoverable errors. Also called internally by assert(). |
| return (main) | Yes | Yes | Returning from main() is equivalent to calling exit(). This is the preferred approach. |
Sample Code
#include <stdio.h>
#include <stdlib.h>
// Cleanup functions registered with atexit.
void cleanup_a(void) { printf("cleanup_a: Removed temporary files.\n"); }
void cleanup_b(void) { printf("cleanup_b: Closed the log.\n"); }
int main(void) {
// Register cleanup functions with atexit (called in reverse order).
atexit(cleanup_a);
atexit(cleanup_b); // Called in order: cleanup_b → cleanup_a.
printf("Starting process.\n");
// Exit on unrecoverable errors such as a failed file open.
FILE *fp = fopen("config.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Configuration file not found.\n");
exit(EXIT_FAILURE); // Runs atexit-registered functions before exiting.
}
// In this sample, fopen fails and exit() is called.
fclose(fp);
return EXIT_SUCCESS;
}
Notes
Returning from main() and calling exit(status) are equivalent. Use exit() only when you need to terminate immediately from a deeply nested function; in most cases, returning normally makes the code flow easier to follow.
Functions registered with atexit() are only called when exit() is used. They are not called on abort() or signal-based forced termination. Open files are automatically flushed and closed on exit(), but dynamically allocated memory is not freed — the OS reclaims it when the process ends.
For checking program state, see also assert().
If you find any errors or copyright issues, please contact us.