🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

How to Fix Segmentation Fault Core Dumped Error in C and C++

⏱️1 min read  ·  151 words

The error Segmentation fault (core dumped) in C or C++ means your program tried to access memory it isn’t allowed to. It’s one of the most common and frustrating C/C++ errors. Here’s how to diagnose and fix every common cause.

What a Segfault Actually Is

A segmentation fault occurs when your program accesses memory outside what the OS granted it — dereferencing an invalid pointer, writing past an array’s bounds, or using freed memory. The OS kills the program to protect the system and dumps its state (the “core dump”).

Cause 1: Dereferencing a NULL Pointer

// 🐛 Accessing a NULL or uninitialized pointer
int *ptr = NULL;
*ptr = 42;          // ❌ segfault — writing to address 0

int *uninitialized;  // points to garbage
*uninitialized = 5;  // ❌ segfault (undefined behavior)

// ✅ Always initialize and check pointers
int value = 42;
int *ptr = &value;
if (ptr != NULL) {
    *ptr = 10;      // safe
}

Cause 2: Buffer Overflow (Out-of-Bounds Access)

// 🐛 Writing past the end of an array
int arr[5];
for (int i = 0; i <= 5; i++) {   // ❌ i=5 is out of bounds
    arr[i] = i;                   // arr[5] doesn't exist
}

// ✅ Correct bounds
for (int i = 0; i < 5; i++) {     // i < 5, not <=
    arr[i] = i;
}

// 🐛 strcpy overflow
char dest[5];
strcpy(dest, "This is too long");  // ❌ overflows dest

// ✅ Use bounded copy
char dest[20];
strncpy(dest, "safe copy", sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';

Cause 3: Use-After-Free (Dangling Pointer)

// 🐛 Using memory after freeing it
int *ptr = malloc(sizeof(int));
*ptr = 42;
free(ptr);
*ptr = 10;          // ❌ segfault — ptr is dangling

// ✅ Set to NULL after freeing
free(ptr);
ptr = NULL;         // prevents accidental reuse
// if (ptr) *ptr = 10;  // now safely skipped

Cause 4: Stack Overflow (Infinite Recursion)

// 🐛 Recursion with no base case exhausts the stack
int factorial(int n) {
    return n * factorial(n - 1);  // ❌ never stops → stack overflow
}

// ✅ Add a base case
int factorial(int n) {
    if (n <= 1) return 1;         // base case
    return n * factorial(n - 1);
}

// 🐛 Huge local array can also overflow the stack
void func() {
    int huge[10000000];  // ❌ too big for the stack
}

// ✅ Allocate large data on the heap
void func() {
    int *huge = malloc(10000000 * sizeof(int));
    // ... use it ...
    free(huge);
}

Debugging with gdb

# Compile with debug symbols
gcc -g -o myprogram myprogram.c

# Run under gdb
gdb ./myprogram
(gdb) run

# When it crashes:
Program received signal SIGSEGV, Segmentation fault.
0x0000... in main () at myprogram.c:15

# See the exact line and call stack
(gdb) backtrace       # shows the call stack
(gdb) print ptr       # inspect the bad pointer
(gdb) frame 1         # move up the stack
(gdb) list            # show surrounding code

Finding Memory Bugs with Valgrind

# Valgrind catches invalid access, leaks, and use-after-free
valgrind --leak-check=full ./myprogram

# Output pinpoints the problem:
# Invalid write of size 4
#    at 0x... in main (myprogram.c:15)
#  Address 0x0 is not stack'd, malloc'd or (recently) free'd

# It shows exactly where and what kind of memory error occurred

Using AddressSanitizer (Fast, Built-In)

# Compile with AddressSanitizer — catches many bugs at runtime
gcc -fsanitize=address -g -o myprogram myprogram.c
./myprogram

# ASan reports:
# ERROR: AddressSanitizer: heap-buffer-overflow
#   WRITE of size 4 at 0x...
#   #0 in main myprogram.c:15
# Much faster than Valgrind and often clearer output

Frequently Asked Questions

Q: What does "core dumped" mean?
A: When the program crashes, the OS writes a "core dump" — a snapshot of the program's memory at the crash. You can load it in gdb (gdb ./program core) to inspect the state at the moment of the crash.

Q: Why does my program crash sometimes but not always?
A: Undefined behavior (like using uninitialized memory or a slight buffer overflow) may not always trigger a visible crash — it depends on what happens to be in memory. This makes such bugs dangerous; use ASan/Valgrind to catch them reliably.

Q: gdb vs Valgrind vs AddressSanitizer — which should I use?
A: AddressSanitizer (compile flag) is fastest and catches most memory bugs — start here. Valgrind is thorough for leaks and doesn't need recompilation. gdb is for inspecting a specific crash interactively. Often you use ASan first, then gdb to dig in.

Q: How do I prevent segfaults in the first place?
A: Initialize pointers, check for NULL before dereferencing, respect array bounds, set pointers to NULL after freeing, and use modern C++ smart pointers (unique_ptr, shared_ptr) which manage memory automatically.

Q: Should I use raw pointers in modern C++?
A: Prefer smart pointers and containers (vector, string) which handle memory safely and eliminate most segfault causes. Raw pointers are still useful for non-owning references, but avoid manual new/delete where RAII types work.

Conclusion

A segmentation fault means invalid memory access — usually a NULL/dangling pointer, buffer overflow, or stack overflow. The debugging workflow: compile with -fsanitize=address -g, run it (AddressSanitizer pinpoints the exact line and bug type), or use gdb's backtrace to see the crash location. To prevent them: initialize pointers, check NULL, respect bounds, NULL-out freed pointers, and in C++ use smart pointers and containers. Modern tools like ASan make once-mysterious segfaults quick to find and fix.

✍️ Leave a Comment

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

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা