Common memory errors — null dereference, buffer overflow, use-after-free, double free, memory leak
WHY do these errors even exist?
In a managed language (Python, Java) the runtime tracks every object: it bounds-checks arrays, knows when memory is free, and garbage-collects. C trusts you completely. A pointer is just a 64-bit integer that names a byte address. The CPU happily reads/writes whatever address you give it. So "errors" are not language exceptions — they are undefined behaviour (UB): the program may crash, corrupt data, or appear to work (the most dangerous case).
The five errors — WHAT each one is
| Error | WHAT happened | The lie you believed |
|---|---|---|
| Null dereference | Used *p where p == NULL |
"p points to an object" |
| Buffer overflow | Wrote past the end of an array | "the array is big enough" |
| Use-after-free | Used memory after free(p) |
"p is still valid" |
| Double free | free(p) twice |
"I only freed it once" |
| Memory leak | malloc with no matching free |
"the OS will clean it up" |

1. Null dereference
WHY it happens: malloc returns NULL when allocation fails; uninitialised or "reset" pointers are often NULL. The OS marks page 0 as unmapped, so touching it traps → segfault.
2. Buffer overflow
WHY it’s catastrophic: C arrays have no length stored with them. Writing past the end clobbers adjacent variables, saved return addresses on the stack, or heap metadata — the classic security exploit.
3. Use-after-free (UAF)
WHY it bites: free(p) does not change p — it only returns the block to the allocator. p is now a dangling pointer. The allocator may hand that block to the next malloc, so your "old" pointer now silently aliases someone else's data.
4. Double free
WHY it's dangerous: modern allocators store bookkeeping (size, next-free) inline; freeing twice can let an attacker corrupt those structures (the "double-free exploit").
5. Memory leak
WHY it matters: unlike the others it usually doesn't crash immediately — it slowly grows the process’s memory until the system thrashes or the OOM-killer strikes. In long-running servers a small leak is fatal.
HOW to prevent all five (the 80/20 core)
Flashcards
What does free(p) do to the variable p itself?
p keeps the old (now dangling) address; free only returns the block to the allocator.Why is p = NULL; after free a powerful habit?
free(NULL) is a guaranteed no-op, so it prevents double free, and a later *p becomes a detectable null deref instead of silent use-after-free.A buffer of N bytes holds a C string of length L; what must hold?
\0).What is undefined behaviour?
Distinguish use-after-free vs double free.
What is a memory leak in conservation terms?
Why does strcpy(buf,"hello world") into char buf[8] overflow?
\0) but buf holds only 8; it writes 4 bytes past the end.Which single check prevents null dereference from malloc?
if (p == NULL) before using the returned pointer.For a loop over int a[5], what condition avoids overflow?
i < 5 (valid indices 0..4), not i <= 5.Recall Feynman: explain it to a 12-year-old
Imagine memory is a row of lockers. A pointer is a sticky note with a locker number on it. Null deref: the note says “locker 0” which doesn’t exist — you reach in and hit the wall (crash). Buffer overflow: your stuff is bigger than your locker, so it spills into the neighbour’s locker and messes up their things. Use-after-free: you gave your locker back to the gym, but you kept the note and still open it — now a stranger’s socks are inside. Double free: you tell the gym “I’m done with this locker” twice — the gym’s record book gets confused. Memory leak: you rented lockers and threw away every note, so nobody can ever empty them, and the gym slowly runs out of lockers. The golden rule: rent one, return it once, and burn the sticky note (set it to NULL) the moment you return it.
Connections
- Pointers in C — every memory error is a pointer pointing wrong.
- malloc and free — the heap allocator whose rules we break.
- Stack vs Heap Memory — overflow corrupts stack frames / return addresses.
- Undefined Behaviour — the umbrella consequence.
- Valgrind and AddressSanitizer — tools that detect all five at runtime.
- Buffer Overflow Exploits — security angle.
- Strings in C and the null terminator — the byte.
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, C mein memory ek lambi line of lockers ki tarah hai, aur pointer ek sticky note hai jis par locker ka number likha hai. C tumhe poori azadi deta hai — koi bound-checking nahi, koi garbage collector nahi. Isliye saari memory errors ek hi galti ke alag-alag roop hain: tumhara pointer wahaan point nahi kar raha jahaan tum samajh rahe ho. Yeh galtiyaan undefined behaviour create karti hain — kabhi crash, kabhi sahi chalega, kabhi chup-chaap data corrupt. Sabse khatarnaak wahi case hai jo "chal raha hai" lagta hai.
Paanch errors yaad rakho: Null dereference — malloc fail hua, NULL mila, par tumne *p kar diya → crash. Buffer overflow — array ka size 8 hai par tumne 12 byte ghusa diye, padosi ki memory kharab. Yaad rakho string ke liye hona chahiye, woh \0 ke liye. Use-after-free — free(p) ke baad bhi p purana address pakde baitha hai (dangling pointer), us se read/write karna. Double free — ek hi block ko do baar free karna, allocator ka record book corrupt. Memory leak — malloc kiya par free kabhi nahi kiya ya pointer kho diya; dheere-dheere RAM khatam.
Ab asli trick — ek hi aadat se 4 bugs marr jaate hain: free(p) ke turant baad p = NULL; likh do. Kyun? Kyunki free(NULL) bilkul safe hai (kuch nahi karta), to double free nahi hoga; aur baad mein *p karoge to woh detectable null deref ban jaayega, silent corruption nahi. Iske saath: har malloc check karo, har block ka ek hi malik, ek malloc ka ek hi free, aur hamesha buffer ka size pass karo (snprintf, fgets). Formula CONF-B yaad rakho — Check, One owner, Null after free, Free once, Bounds. Bas itna discipline aur tumhare programs crash nahi karenge.