Menu
Coddy logo textTech

What Is a Segmentation Fault?

A segmentation fault, or segfault, is a crash that happens when a program tries to read or write memory it is not allowed to access, such as address 0 through a null pointer. The operating system stops the program with the SIGSEGV signal.

By Kevin Spektor, Co-founder & CTO

Updated September 24, 2026

A C program prints its first line and then stops with a message nobody wrote:

#include <stdio.h>

int main(void) {
    int *score = NULL;

    printf("About to read the score\n");
    printf("Score: %d\n", *score);
    return 0;
}
About to read the score
bash: line 1: 64030 Segmentation fault: 11  ./seg

That output is from bash on macOS, where 64030 is the process ID and 11 is the signal number. On Linux the same crash usually reads Segmentation fault (core dumped). Either way, the program never printed the score. score holds address 0, and *score asks the processor to read the memory at that address, which no program is allowed to do.

How a segmentation fault happens

Every program runs in its own virtual address space, a huge range of addresses that the operating system fills in piece by piece. It maps the program's code, its global variables, its stack and its heap into that range, in blocks called pages (4 KB on most x86 Linux systems, 16 KB on Macs with Apple silicon). Most addresses are left unmapped, and address 0 is always among them so that null pointer bugs are caught.

  1. The program executes an instruction that reads or writes an address. Here it is the read of *score, address 0.
  2. The processor's memory management unit looks the address up in the page table. The page is not mapped, or the program is trying to write to a page that is read-only.
  3. The processor stops the instruction and hands control to the kernel with a page fault.
  4. The kernel checks whether the access could be legal, for example a stack that needs to grow. It is not, so the kernel sends the process signal 11, SIGSEGV.
  5. The default action for SIGSEGV is to end the process and, when the system allows it, save a core dump. The shell then prints the message and sets the exit status to 139, which is 128 plus the signal number.

So a segmentation fault is not reported by the compiler, and it is not an exception the language raises. It is the hardware and the kernel protecting memory, which makes it a runtime error of the most abrupt kind. Windows handles the same event as an access violation, exception code 0xC0000005.

Common causes of segmentation faults

C and C++ let a program compute any address and use it, so the causes come down to using an address that is not valid.

  • Dereferencing a null pointer. int *p = NULL; *p = 5; A function that returns NULL on failure, such as malloc or fopen, leads here when its result is not checked.
  • An index far past the end of an array. C does not check bounds, so arr[1000000] is simply an address a million elements further on.
  • Using memory after free. The pointer still holds the old address, but the memory no longer belongs to you.
  • An uninitialized pointer. int *p; *p = 5; writes through whatever garbage value p happens to hold.
  • Stack overflow. A recursive function with no stopping case keeps adding stack frames until it runs off the end of the stack. The example below crashed on macOS with Segmentation fault: 11 and exit status 139.
  • Writing to a string literal. char *name = "coddy"; name[0] = 'C'; tries to change read-only memory. On Linux that is a segfault. On macOS the same program stopped with Bus error: 10, a related signal.
#include <stdio.h>

int depth(int n) {
    return depth(n + 1) + 1;   /* never stops calling itself */
}

int main(void) {
    printf("%d\n", depth(0));
    return 0;
}

A small mistake often does not crash at all, which makes it more dangerous. This loop reads one element past the end of a three-element array:

#include <stdio.h>

int main(void) {
    int scores[3] = {72, 88, 95};
    int total = 0;

    for (int i = 0; i <= 3; i++) {   /* <= reads scores[3] */
        total += scores[i];
    }
    printf("Total: %d\n", total);
    return 0;
}

Compiled with Clang on a Mac, it printed Total: 256. The correct total is 255. scores[3] was the next 4 bytes of the stack, which belonged to the program, so no fault occurred and the garbage value was added silently. The operating system only stops accesses to memory the program does not own at all.

The fix for both mistakes is the same habit: know how many elements there are, and check a pointer before you follow it.

Best: 95
No scores, nothing to read

What "core dumped" means

A core dump is a file that holds a copy of the program's memory at the moment it crashed. A debugger can open it later and show exactly where the program was and what its variables held: gdb ./app core. On many Linux distributions, systemd-coredump collects these files, and coredumpctl list shows them. When core dumps are turned off, for example with ulimit -c 0, the message is just Segmentation fault, without the words in parentheses.

How to find the line that crashed

The line where the program crashes is often not the line with the bug. A pointer can become invalid in one function and be used in another much later. These tools show both.

A debugger. Compile with debug information and run the program inside the debugger. When it stops, bt (backtrace) prints the chain of function calls with file names and line numbers. On Linux the debugger is usually gdb; on macOS it is lldb, where bt works the same way.

gcc -g app.c -o app
gdb ./app
(gdb) run
(gdb) bt

AddressSanitizer. Compile with -fsanitize=address (GCC and Clang both support it) and run the program normally. Instead of a bare segfault, it prints a report that names the kind of mistake, such as heap-use-after-free or stack-buffer-overflow, with the line that made the access and the line that allocated the memory. It also catches the quiet one-past-the-end read above, which never crashes on its own.

Valgrind. On Linux, valgrind ./app runs an unmodified program and reports every invalid read or write, such as Invalid read of size 4.

Segmentation faults in other languages

Python, Java and JavaScript check every index and every reference before using it, so the same mistakes become exceptions with clear messages: IndexError or AttributeError in Python, ArrayIndexOutOfBoundsException or NullPointerException in Java, TypeError in JavaScript. Those can be caught with exception handling. A segfault cannot be handled that way: it is a signal, and a C++ catch block does not see it.

Python programs can still segfault when C code fails underneath them. This line asks ctypes to read address 0:

import ctypes
ctypes.string_at(0)

Run with python3 -X faulthandler, Python 3.12 printed Fatal Python error: Segmentation fault, followed by the Python lines that were running. The same crash happens when a C extension or a native library has a memory bug. Rust takes a different approach: its compiler rejects most code that could access invalid memory before the program is built.

Where to go next

The C guide to segmentation faults walks through each cause with a minimal program and its fix. To avoid the mistakes in the first place, read about pointers, null pointers and the stack and the heap, then practice them in the C course. For how errors are reported in languages that check memory for you, see the runtime error page.

Frequently Asked Questions

How do you fix a segmentation fault?
First find the line: compile with -g and run the program under gdb or lldb, then type bt after the crash, or compile with -fsanitize=address for a detailed report. Then fix the pointer or index that line uses: check pointers for NULL, keep array indexes below the length, stop using memory after free, and make sure recursion ends.
Is a segmentation fault a memory leak?
No, they are opposite problems. A memory leak is memory the program allocated and never freed, so it keeps running while using more and more memory. A segmentation fault is an access to memory the program does not own, and the program is stopped at once. Mistakes with free, such as using a pointer after freeing it, can cause segfaults, while forgetting free causes leaks.
Why is it called a segmentation fault?
The name comes from memory segmentation, an older design in which a program's memory was divided into segments with fixed limits, and touching an address outside your segment was a fault. Modern systems manage memory in pages instead, but the name, and the signal name SIGSEGV, stayed. Windows calls the same event an access violation.
Can Python have a segmentation fault?
Ordinary Python code does not cause one, because Python checks every index and reference and raises an exception instead. A Python program can still segfault inside C code: a C extension module, a library such as a machine learning framework, or ctypes. Running python -X faulthandler script.py prints the Python lines that were running when it crashed.
What does exit code 139 mean?
Exit code 139 means the process was killed by signal 11, which is SIGSEGV, a segmentation fault. Shells report a death by signal as 128 plus the signal number, and 128 + 11 = 139. In Docker and Kubernetes, a container that exits with 139 had its main process segfault.
Coddy programming languages illustration

Learn to code with Coddy

GET STARTED