← Back to C Course | Chapter 12: Advanced Topics | Lesson 16 of 20

C Error Handling

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

c
#include <stdio.h>
int main() {
	FILE *fp = fopen("nonexistent.txt", "r");
	if (fp == NULL) {
		printf("Failed to open");
		return 1;
	}
	fclose(fp);
	return 0;
}

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

c
#include <stdio.h>
int main() {
	int a = 10, b = 0;
	if (b == 0) {
		printf("Cannot divide by zero");
	} else {
		printf("%d", a / b);
	}
	return 0;
}

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

c
#include <stdio.h>
#include <stdlib.h>
int main() {
	int *ptr = malloc(sizeof(int));
	if (ptr == NULL) {
		printf("Allocation failed");
		return 1;
	}
	*ptr = 5;
	printf("%d", *ptr);
	free(ptr);
	return 0;
}

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

c
#include <stdio.h>
int main() {
	int userInput = -1;
	int value = (userInput < 0) ? 0 : userInput;
	printf("%d", value);
	return 0;
}

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

c
#include <stdio.h>
#include <stdlib.h>
int main() {
	int criticalError = 1;
	if (criticalError) {
		printf("Unrecoverable error");
		exit(1);
	}
	return 0;
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.