Pointer to pointer
WHAT is it?
Why does the type need **?
A type in C tells the compiler how to interpret the bytes at the target address. When you write *pp, the compiler must know "the thing at pp is itself a pointer," so it needs int **. One * would mean "dereferencing gives an int" — wrong, here dereferencing gives a pointer.
HOW dereferencing peels layers
Each * removes one level of indirection.
| Expression | Meaning | Value (using addresses below) |
|---|---|---|
pp |
address of p |
&p = 0x300 |
*pp |
the value stored in p |
&x = 0x100 |
**pp |
the value stored in x |
42 |

WHY do we need it? (the 80/20 core)
The 20% of use-cases that cover 80% of real code:
- Modifying a pointer inside a function. C passes by value. To change the caller's pointer, you must pass its address → an
int **. - Arrays of strings / 2-D dynamic arrays.
char **argv,char **lines. - Linked-list/tree edits where you must update the node-pointer itself.
Common mistakes (Steel-manned)
Flashcards
What does int **pp store?
If pp = &p and p = &x, what is *pp?
p, which is &x (the address of x).If pp = &p and p = &x, what is **pp?
x — full dereference to the int.Why pass int ** to a function?
How many * to modify an int vs an int* inside a function?
* (pass int*) for an int; two * (pass int**) for a pointer.What is the type of *pp when pp is int**?
int* — a pointer to int.In char **argv, what is *argv?
char* — pointer to the first command-line string.Why does each * "peel a layer"?
What happens to **pp if *pp (i.e. p) is NULL?
Does *pp = NULL change the final value x?
p; x is untouched.Recall Feynman: explain to a 12-year-old
Imagine a treasure. You have a note that says "the treasure is in box A." That note is a pointer. Now you have another note that says "the first note is on the kitchen table." That second note is a pointer to a pointer — it doesn't point to the treasure directly, it points to the note that points to the treasure. To get the treasure you read note 2 → walk to the table → read note 1 → walk to box A → open it. Each * in C is one "walk to where the note says." Two * means two walks, so you reach the treasure (42). One * only gets you to note 1.
Connections
- Pointers basics — the single-level foundation this builds on.
- Pass by value vs pass by reference — why
**is needed for functions. - Dynamic memory allocation (malloc) —
int **to return allocated memory. - Command line arguments (argv) —
char **argvin practice. - Pointer arithmetic — how
pp+1steps bysizeof(pointer). - 2-D arrays vs pointer to pointer — subtle differences in memory layout.
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, pointer ek aisa variable hai jo kisi doosre variable ka address store karta hai. Ab "pointer to pointer" ka matlab simple hai — ek aisa box jo kisi aur pointer ka address rakhta hai. Jaise int x = 42; phir int *p = &x; (p ke andar x ka address), aur int **pp = &p; (pp ke andar p ka address). Bas ek extra level of indirection add ho gaya, kuch magic nahi.
Yaad rakhne ka rule: har * ek arrow ko follow karta hai, ek layer chheelta hai. *pp aapko p deta hai (yaani &x), aur **pp aapko x ki value 42 deta hai. & upar le jaata hai (layer wrap karta hai), * neeche le jaata hai (layer peel karta hai). Isko mantra ki tarah yaad rakho: "Star peels, ampersand wraps."
Yeh kyun zaroori hai? Sabse bada reason — C mein function ko sab kuch by value milta hai. Agar aap function ke andar caller ka pointer hi change karna chahte ho (jaise malloc se memory de kar), toh aapko us pointer ka address bhejna padega, yaani int **. Agar aap sirf int* bhejoge, function apni local copy change karega, original waisa ka waisa reh jaayega. Isiliye void f(int **p) pattern bohot common hai.
Galti se bachna: *pp ek pointer hai (int*), aur **pp ek value hai (int) — dono interchangeable nahi hain. Arrows ginna seekh lo. Aur agar beech ka link NULL ya garbage hai, toh **pp crash kar dega. Real life examples: char **argv (command line strings), 2-D dynamic arrays, aur linked list ke node edits — sab mein yahi concept kaam aata hai.