🇯🇵 日本語 | 🇺🇸 English

Lesson 34: Runtime Errors and Segfaults

Causes of segmentation faults in C and how to fix them — your complete guide to runtime errors.

📖 What you'll learn on this page
✅ Must-know essentials
  • A segmentation fault means accessing forbidden memory
  • NULL dereference, out-of-bounds access, and use-before-init are the top causes
  • Division by zero and stack overflow
⭐ Read if you have time
  • The dangers of undefined behavior
  • Detection with valgrind and sanitizers
  • Core dumps and post-mortem debugging with gdb

What are Runtime Errors — It Compiled, but...

A successful compile just means the syntax is correct. A runtime error is when the program crashes while running. The compiler can't catch these, which makes them harder to debug.
Segmentation Fault
Reading or writing forbidden memory. The most common runtime error.
Bus Error
Memory alignment violations. Whether they occur depends on the platform.
Floating Point Exception
Division by zero (x / 0).
Infinite loop / freeze
The program never terminates. Kill it with Ctrl+C.
General approach: (1) use printf to find out how far execution gets, (2) print the values of suspicious variables, and (3) carefully check array indices and pointers.

Segmentation Fault — Top Causes

Segmentation fault (core dumped) is the error beginners run into most often. It means "you touched memory you weren't allowed to."

Top 5 causes

1
Out-of-bounds array access
int a[5];
a[10] = 99;  // only a[0]..a[4] exist; writing a[10] = instant crash

// Common mistake: wrong loop bound
for (int i = 0; i <= 5; i++)  // accesses a[5] when i=5 -> NG
  a[i] = i;
2
Dereferencing a NULL pointer
int *p = NULL;
*p = 10;  // writing to the address NULL points to -> Segfault

// Fix: NULL-check before use
if (p != NULL) { *p = 10; }
3
Missing & in scanf
int x;
scanf("%d", x);   // NG: uses the "value" of x as an address -> crash
scanf("%d", &x);  // OK: passes the "address" of x
4
Using an uninitialized pointer
int *p;     // uninitialized -> contains garbage address
*p = 42;    // writing to a garbage address -> Segfault

// Fix: always initialize, or allocate with malloc before use
5
Stack overflow (infinite recursion)
int fact(int n) {
  return n * fact(n - 1); // no base case -> recurses forever -> stack overflow
}
// Fix: add if (n <= 1) return 1;

Memory-Related Errors — Hidden Landmines

Memory bugs can surface as wrong results without ever triggering a segfault.
Buffer overrun
Writing past the end of an array corrupts neighboring memory.
char name[5];
strcpy(name, "HelloWorld"); // only 5 bytes but 10+NUL -> overflow

// Fix: strncpy(name, "Hello", sizeof(name)-1);
Memory leak
Forgetting to free memory allocated by malloc leaves unreachable memory that accumulates over time.
int *p = malloc(sizeof(int) * 100);
// ... use p ...
// forgot free(p); -> memory leak
Dangling pointer / double free
Using a pointer after it's been freed leads to unpredictable behavior.
free(p);
*p = 10;   // writing to freed memory -> undefined behavior
free(p);   // double free -> possible crash

// Fix: set p = NULL; after free

Logic Errors — It Runs But the Answer is Wrong

No crash, but the result is wrong. These are the hardest bugs to track down — printf debugging is your best friend.
Integer division pitfall
int a = 7, b = 2;
double avg = a / b;     // -> 3.000000 (not 3.5!)
double avg = (double)a / b; // -> 3.500000 (OK)
Integer divided by integer truncates the fractional part. Cast one side to double.
Operator precedence
if (x & 1 == 0)   // parsed as x & (1==0) - not what you meant!
if ((x & 1) == 0) // OK: explicit parens
Bitwise vs. comparison precedence is counter-intuitive. When in doubt, add parentheses.
Missing break in switch (fall-through)
switch (n) {
  case 1: printf("one\n");  // no break -> case 2 and case 3 also run
  case 2: printf("two\n");
  case 3: printf("three\n");
}
Stray semicolon after if
if (x > 0);  // ← this ; ends the if statement
{
  printf("positive\n"); // ← always runs!
}

Troubleshooting Checklist

When you hit an error, walk through this checklist from top to bottom.

If you see a Segmentation Fault

When results are wrong

When you have lots of compile errors

← Previous lesson
Lesson 33: Compile Errors

Related lessons

Reference
Lesson 33: Compile Errors Dictionary
A catalog of C compile errors and how to fix them.
Loops, Arrays, Strings
Lesson 17: Debugging Techniques
How to debug C programs.
Advanced
Lesson 27: Pointer Basics
Understand C pointers with memory visualization.

FAQ

Q. What is the difference between compile errors and runtime errors?

A. Compile errors are syntax problems caught during compilation; no executable is produced. Runtime errors occur while the program is running — the code compiles but the program crashes. Runtime errors are harder to detect.

Q. I got a segmentation fault. What causes it?

A. Segmentation faults come from illegal memory access. The main culprits: (1) dereferencing a NULL pointer, (2) accessing freed memory, (3) out-of-bounds array access, and (4) stack overflow. Review your pointer and memory handling.

Q. How do I debug an infinite loop?

A. (1) Check the loop condition and exit criterion. (2) Use printf() on loop variables to see where they diverge from your expectations. (3) A step debugger is also effective. Most infinite loops come from bad loop conditions or a missing increment.

Q. How do I find memory corruption?

A. Memory corruption is tricky because the symptoms often appear far from the actual cause. Effective tools include (1) valgrind (Linux/Mac), (2) sanitizers like UBSan and ASan, and (3) careful review of your array and pointer usage.

Review Quiz

Check your understanding.

Q1. What is the main cause of segmentation faults?

Syntax errors
Illegal memory access
Wrong variable names

Common causes include NULL pointer dereferences, out-of-bounds array access, and using freed memory. The compiler can't catch any of these.

Q2. What happens when you divide by 0?

Compile error
Runtime error (division by zero)
The result is 0

Integer division by 0 is a runtime error. If you're dividing by a variable, check that it's not zero first.

Q3. How do you fix an infinite loop?

Change the compiler settings
Revisit the loop's exit condition
Change the variable type

Infinite loops happen when the exit condition is never met. Check for a missing counter update or flawed condition logic.

Share this article
Share on X Share on Facebook