C Error Handling
In this page:
if (function_name(arguments) == error_value) {
// handle the failure
}
if (divisor == 0) {
// avoid dividing by zero
}
Checking Return Values
Standard library functions signal failure through their return value — often NULL for a pointer-returning function or -1 for an integer-returning one — so checking that return value immediately after the call is the most basic and most frequently skipped error-handling habit in C.
Example: Checking Return Values
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
FILE *fp = fopen("nonexistent.txt", "r");
// Check whether fp == NULL
if (fp == NULL) {
// Print formatted text to the screen
printf("Failed to open");
// Send 1 back to the caller
return 1;
}
fclose(fp);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Handling Division by Zero
C performs no automatic check for division by zero, so dividing an integer by a variable that happens to be zero crashes the program (or, for floating-point division, produces inf or nan) rather than raising a catchable exception.
Validating a divisor with a plain if before dividing is the only reliable defense.
Example: Handling Division by Zero
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
int a = 10, b = 0;
// Check whether b == 0
if (b == 0) {
// Print formatted text to the screen
printf("Cannot divide by zero");
} else {
// Print formatted text to the screen
printf("%d", a / b);
}
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Handling Allocation Failures
When dynamic memory is exhausted, malloc() and its relatives return NULL instead of a valid pointer, and writing through that NULL pointer without checking for it first crashes the program.
Always test the return value of an allocation call before using the memory it was supposed to provide.
Example: Handling Allocation Failures
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
// Allocate memory on the heap
int *ptr = malloc(sizeof(int));
// Check whether ptr == NULL
if (ptr == NULL) {
// Print formatted text to the screen
printf("Allocation failed");
// Send 1 back to the caller
return 1;
}
*ptr = 5;
// Print formatted text to the screen
printf("%d", *ptr);
free(ptr);
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Setting Fallback Defaults
When an operation can plausibly fail but the program can still make progress, falling back to a sensible default value (rather than propagating garbage or an uninitialized value) keeps execution stable instead of letting one bad reading corrupt everything downstream.
Example: Setting Fallback Defaults
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
// Declare userInput and set it to -1
int userInput = -1;
int value = (userInput < 0) ? 0 : userInput;
// Print formatted text to the screen
printf("%d", value);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Graceful Termination
When an error truly can't be recovered from, exiting cleanly with a non-zero status code (typically via exit(1) or a non-zero return from main) tells any calling shell script or parent process that something went wrong, which matters for automation that checks a program's exit status.
Example: Graceful Termination
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
// Declare criticalError and set it to 1
int criticalError = 1;
// Check whether criticalError
if (criticalError) {
// Print formatted text to the screen
printf("Unrecoverable error");
exit(1);
}
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Ignoring return values of functions such as
fopenandmalloc. - Not checking the result of
mallocbefore using the pointer. - Not checking for a zero divisor before dividing, which is undefined behavior for integers.
Chapter Quiz — Complete all 20 topics to unlock
0/20 topics done
Complete these topics first:
- C typedef
- C Type Casting
- C Bit Fields
- C Variable Length Arrays
- C Command Line Arguments
- C Function Pointers
- C Callback Functions
- C Multidimensional Pointer
- C string.h Functions
- C stdlib.h Functions
- C math.h Functions
- C time.h Functions
- C ctype.h Functions
- C errno.h
- C assert.h
- C Error Handling
- C Debugging Techniques
- C Code Style & Best Practices
- C Common Mistakes
- C Interview Questions