SIGSEGV

Segfault After scanf? You Forgot the Pointer Address

Segmentation fault right after scanf usually means you passed an uninitialized pointer to scanf instead of the address of a variable. Here's the fastest fix first.

I know that crash is infuriating. You wrote a 20-line C program, it compiles clean, then the moment you type a number and hit Enter you get the big red banner: Segmentation fault (core dumped). The frustrating part is that the compiler said nothing. That's because this isn't a compile error — it's your program trying to write to memory it doesn't own.

The trigger is almost always the same: scanf needs an address, not a value. If you hand it an uninitialized pointer, or you forget the & on a plain variable, it tries to write your typed number into a garbage location. The OS steps in and kills the process. Let's walk through the fixes from fastest to deepest. Stop whenever it works.

Fix 1 — The 30-Second Fix: Check Your & and Your Pointer

Ninety percent of these crashes live in one line. Look at every scanf call and ask: does this argument point at real memory?

Here's the classic broken version:

#include <stdio.h>

int main(void) {
    int *num;              // uninitialized pointer — points nowhere
    printf("Enter a number: ");
    scanf("%d", num);      // BUG: writing to garbage address
    printf("%d\n", *num);
    return 0;
}

Two ways to repair it. If you just want an int, drop the pointer entirely and use the address-of operator:

int num;
scanf("%d", &num);

If you actually need a pointer (say you're passing it to a function later), give it a real target:

int value;
int *num = &value;
scanf("%d", num);

Same rule for arrays of char: char name[64]; scanf("%63s", name); — no & needed because the array name already decays to a pointer. Getting that backwards is a rite of passage. I did it for a solid month in college.

Rebuild and run. If it works, you're done. If it still segfaults, keep going.

Fix 2 — The 5-Minute Fix: Compile With Warnings and Run Under gdb

When Fix 1 doesn't cut it, you've got a pointer bug the compiler would have told you about if you'd asked nicely. Turn warnings way up:

gcc -Wall -Wextra -Wuninitialized -g myprog.c -o myprog

On Clang, -Wall -Wextra -g gets you there too. Those flags will flag an uninitialized pointer, a missing & on a scalar, and mismatched format specifiers. Read every warning — don't scroll past them.

Still crashing? Get the exact line. With -g compiled in, run gdb:

gdb ./myprog
(gdb) run
# ... type your input, let it crash ...
(gdb) bt
(gdb) frame 0
(gdb) print num

The backtrace points you straight at the offending line. print num on that frame shows you the address it was trying to write to — if it looks like 0x0 or something absurd, that's your smoking gun. A NULL dereference and an uninitialized-pointer dereference look almost identical in gdb; both are the same class of mistake.

A quick tell: if the crash happens on the very first scanf after your prompt prints, it's this bug. If it happens on the tenth iteration of a loop, you've probably walked off the end of an array instead — check your loop bounds and index < size conditions.

Fix 3 — The 15-Minute Fix: Valgrind, Format Strings, and the Weird Cases

If gdb says the pointer looks valid but you still crash, the write is going somewhere — just not where you meant. This is where Valgrind earns its keep:

valgrind --track-origins=yes ./myprog

Valgrind reports "Use of uninitialised value" and traces where the garbage came from. It's slower but it catches the pointer that looks initialized because it happens to hold a leftover stack value. That's the nasty case — int *p; that randomly points into a valid-looking address, so it doesn't always crash. It crashes only on some machines, some runs. Valgrind nails those.

Three other culprits worth ruling out while you're here:

  1. Format string mismatch. scanf("%d", &myDouble); writes 4 bytes into an 8-byte double, or scanf("%s", &myInt); tries to write a whole string into a 4-byte slot. Both can segfault. Match your specifier to your type.
  2. Null from malloc. int *a = malloc(sizeof(int)); scanf("%d", a); crashes if malloc returned NULL. Check it: if (!a) { perror("malloc"); return 1; }
  3. Writing to a string literal. char *s = "hello"; scanf("%s", s); — literal strings live in read-only memory. Use char s[64]; instead.

Here's a quick reference for what's safe to pass to scanf:

ScenarioPass thisResult
int x;&xSafe
int *p; (uninitialized)pSegfault
int *p = &x;pSafe
char buf[64];bufSafe
char *s = "lit";sSegfault (read-only)

Why This Bug Keeps Biting People

C gives you a pointer that compiles fine and runs fine right up until it doesn't. Unlike Rust or Go, nothing stops you from handing scanf a pointer to nowhere. The language assumes you know what you're doing. That's the deal you signed up for.

The habit that saves you every time: before every scanf, ask out loud, "where is this writing to?" If the answer is anything other than "the address of a variable I declared," stop and fix it. Turn on -Wall -Wextra and leave them on permanently. And when something only crashes on your friend's laptop, reach for Valgrind before you reach for Stack Overflow.

You'll stop seeing core dumps soon enough. Then you get to move on to the fun bugs, like the off-by-one that corrupts your malloc heap at 2am.

Related Errors in Programming & Dev Tools
VS Code 1.85 JavaScript IntelliSense Dead: Real Fix java.lang.OutOfMemoryError: Java heap space Fixing Java OutOfMemoryError: Java heap space Could not find a version that satisfies the requirement Pip install fails: 'Could not find a version that satisfies the requirement' 0XC000008E Fixing 0XC000008E: Floating-point division by zero in C++

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.