5.1.18C Programming

Common memory errors — null dereference, buffer overflow, use-after-free, double free, memory leak

2,152 words10 min readdifficulty · medium

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"
Figure — Common memory errors — null dereference, buffer overflow, use-after-free, double free, memory leak

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?
Nothing — 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?
L+1NL + 1 \le N (the +1 is the terminating \0).
What is undefined behaviour?
Behaviour the C standard imposes no requirements on; the compiler may assume it never occurs, so bugs can crash, work, or silently corrupt.
Distinguish use-after-free vs double free.
UAF = dereferencing freed memory; double free = calling free twice on the same address.
What is a memory leak in conservation terms?
Allocations exceed frees of reachable blocks (A > F); a block whose last pointer was lost without being freed.
Why does strcpy(buf,"hello world") into char buf[8] overflow?
The source is 12 bytes (11 chars + \0) but buf holds only 8; it writes 4 bytes past the end.
Which single check prevents null dereference from malloc?
Test 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 +1+1 byte.

Concept Map

leads to

root cause

manifests as

manifests as

manifests as

manifests as

manifests as

from

because

enables

after

calls twice

missing

C no memory supervision

Undefined Behaviour

Bad pointer use

Null dereference

Buffer overflow

Use-after-free

Double free

Memory leak

malloc returns NULL

Arrays store no length

Security exploit

free called

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 dereferencemalloc 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 L+1NL+1 \le N hona chahiye, woh +1+1 \0 ke liye. Use-after-freefree(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 leakmalloc 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.

Go deeper — visual, from zero

Test yourself — C Programming

Connections