How to Debug Segmentation Faults in C: 3 Common Causes and How to Fix Them

When my friends and I were first learning how to code in C, we actually liked compiler warnings and compile errors.

That might sound strange, but when we got a warning or compile error, it usually gave us an idea of what was wrong with our code. We knew where to start looking.

The error we hated the most was the segmentation fault.

We would compile our program, everything would seem fine, and then we would run it and suddenly get a segmentation fault error.

The annoying part was that we often had no clue what was causing it.

If you’re running into segmentation faults in your C program, this article will go over three common reasons they happen and how you can start debugging them.

What Is a Segmentation Fault?

A segmentation fault usually happens when your program tries to access memory that it should not access.

In this article, we will look at three common examples:

  1. Dereferencing a pointer that has not been properly initialized
  2. Accessing an array outside of its bounds
  3. Using recursion that eventually causes a stack overflow

Before getting into those examples, let’s start with a simple debugging technique.

How to Debug a Segmentation Fault with printf

When I was learning how to code, one of the first ways I learned to debug a segmentation fault was by using printf statements.

The basic idea is simple. Put printf statements before and after code that you suspect might be causing the problem.

For example:

printf("Before suspicious code\n");

// Suspicious code

printf("After suspicious code\n");

If the first printf statement appears but the second one does not, then you know the segmentation fault is happening somewhere between those two statements.

As a beginner, I would keep adding more printf statements until I could isolate the exact line of code causing the issue.

You can also temporarily comment out a suspicious line of code and run the program again. If the segmentation fault disappears, that gives you a big clue that something is wrong with that line.

This is a simple approach, but it can be very effective when you’re trying to figure out where your program is crashing.

Now let’s look at three common causes of segmentation faults.

1. Dereferencing an Uninitialized Pointer

The first common cause is dereferencing a pointer that has not been properly initialized.

Imagine you have a pointer and then try to dereference it:

int *ptr = NULL;
*ptr = 42;

The program does not have valid memory allocated for ptr to write to.

So when you dereference it and try to store the value 42, you can get a segmentation fault.

One way to fix this is to point the pointer to a valid variable:

int a = 9;
int *ptr = &a;

*ptr = 42;

Now ptr contains the address of a, so dereferencing it gives you a valid location to access.

As a beginner, you might not immediately know whether a particular pointer operation is legal. This is where debugging with printf statements can help.

You can place a printf before and after the suspicious code to see whether the program gets past that line.

Once you know which line is causing the segmentation fault, you can investigate what that line is trying to do.

2. Accessing an Array Out of Bounds

Another common cause of a segmentation fault is accessing an array outside of its bounds.

Suppose you have an array with five elements:

int scores[5] = {10, 20, 30, 40, 50};

The valid indexes are:

0, 1, 2, 3, 4

But imagine your program tries to access:

scores[4000];

That index is far outside of the array.

This is undefined behavior. The program may crash with a segmentation fault, but it might also appear to work and return a random value.

That can make this kind of bug especially confusing.

For example, your program might access an invalid index and print a number that was never actually stored in your array.

A useful debugging technique is to print both the index and the value:

printf("Index: %d\n", index);
printf("Score: %d\n", scores[index]);

If you see an index like 4000 when your array only has five elements, you immediately have a clue about the problem.

In that situation, you need to make sure your index stays within the valid range of the array.

For an array with five elements, valid indexes are from 0 through 4.

3. Infinite Recursion and Stack Overflow

The third common cause is a stack overflow caused by recursion.

Every time you call a function, your program allocates memory for that function call. This memory is stored in what is called the stack.

For example, if you call a function, a stack frame is created for that function.

When the function returns, that stack frame can be removed.

But recursive functions work differently because the function calls itself.

Consider this example:

void recursiveTrap(int counter)
{
    recursiveTrap(counter + 1);
}

This function never stops calling itself.

Each recursive call adds another stack frame. Eventually, the program runs out of stack space and can crash with a segmentation fault.

One way to debug this is to print the counter:

printf("Stack frame depth: %d\n", counter);

If the number keeps increasing and increasing, you may have an infinite recursion problem.

The solution is to create a condition that stops the recursion:

void recursiveTrap(int counter)
{
    if (counter == 5)
    {
        return;
    }

    recursiveTrap(counter + 1);
}

Now the recursion stops when the counter reaches 5.

This is called a base case.

Without a condition that allows the function to return, a recursive function can continue adding stack frames until the program eventually runs out of stack memory.

A Segmentation Fault Is Not Always Caused by Direct Recursion

Sometimes the problem is not a function directly calling itself.

Your program may have one function that calls another function, which calls another function, which calls another function.

If enough functions are nested and your program reaches the limit of available stack memory, you can still run into a stack overflow.

In some cases, you may need to simplify the call structure of your program.

In other cases, depending on your environment and project, you may need to increase the amount of memory available for the stack.

This can be especially important when you’re working with libraries that you don’t completely control.

A library function may call another function, which calls another function, and you may not have direct control over how deep that call chain becomes.

Summary: 3 Common Causes of Segmentation Faults in C

Let’s quickly review the three common causes discussed in this article.

1. Dereferencing an uninitialized pointer

Your pointer needs to point to valid memory before you dereference it.

2. Accessing an array out of bounds

Make sure your array index is within the valid range of the array.

3. Infinite recursion

Recursive functions need a condition that eventually stops them from calling themselves.

My General Tip for Debugging Segmentation Faults

My general tip for beginners is to use a lot of printf statements.

That was one of the most reliable ways for me to find where an issue was happening when I was first starting out.

Put printf statements throughout your program to see how far the program gets before it crashes.

Once you isolate the suspicious line of code, you can temporarily comment it out and run the program again.

If the program works after you comment out that line, you know that you have found an important clue.

Then you can focus your debugging effort on understanding what is wrong with that specific piece of code.

Segmentation faults can be frustrating because your program may compile successfully and then crash when you run it.

But if you isolate the problem step by step, the error becomes much easier to investigate.

The goal is not to guess what is causing the crash.

Instead, use debugging techniques to narrow down where the problem is happening. Then investigate what your code is doing with pointers, array indexes, memory, and function calls at that location.

That approach can help you debug not only segmentation faults, but many other problems in your C programs as well.

Leave a Reply

Your email address will not be published. Required fields are marked *