Visual walkthrough — Common memory errors — null dereference, buffer overflow, use-after-free, double free, memory leak
5.1.18 · D2· Coding › C Programming › Common memory errors — null dereference, buffer overflow, us
Kuch bhi draw karne se pehle, teen seedhi-saadhi baatein jo hum baar baar use karenge. Agar parent note ne inhe assume kiya tha, toh hum yahan unhe build karte hain.
Poore samay, jab bhi hum woh line cross karte hain jo standard forbid karta hai, hum Undefined Behaviour mein hain — program crash kar sakta hai, kaam kar sakta hai, silently corrupt ho sakta hai. Yehi ambiguity hai isliye hum itni saavdhani se draw karte hain.
Step 1 — Memory strip aur pointer draw karo
KYA. Hum memory ko boxes ki ek horizontal strip ke roop mein lay out karte hain, har ek apne address ke saath labeled. Hum ek chota block malloc karte hain aur returned address ko p ke andar land hote draw karte hain.
KYUN. Neeche har error "arrow from p galat jagah ya galat waqt landa hai." Toh pehle hume, kaagaz par, fix karna hoga ki "sahi jagah sahi waqt" kaisa dikhta hai. Yeh hamara reference frame hai.
TASVEER. 
int *p = malloc(4); // 4 bytes for one intCode ke har term ko padhte hain:
malloc(4)— 4 boxes ka ek block maangta hai. Iski value box #100 ka address hai (maan lo).p— ek pointer variable; is line ke baad,pke andar stored number hai.- Figure mein amber arrow woh stored number hi hai: woh
pse shuru hota hai aur block ke pehle box par land karta hai.
Har agle step mein in teeno conditions mein se ek fail hoti hai, draw ki gayi.
Step 2 — Condition 1 todo: arrow box #0 par point karta hai (null deref)
KYA. Maano malloc fail ho gaya aur NULL return kiya, yaani address . Ab p ka arrow box #0 par point karta hai. Hum phir bhi usske through likhte hain.
KYUN. malloc tab NULL return karta hai jab system memory nahi de sakta. Box #0 jaan-bujhkar unmapped chhoda jata hai — wahan koi real box nahi hota — toh CPU us waqt trap karta hai jab tum use touch karte ho. Yeh sabse safe memory error hai theek isi liye kyunki yeh usually loudly crash karta hai silently corrupt hone ke bajay.
TASVEER. 
int *p = malloc(HUGE); // fails → p == NULL (address 0)
*p = 42; // arrow lands on the wall → segfaultHar term:
p == NULL—pke andar ka number hai. Figure mein arrow strip se baayein hatched "unmapped wall" mein mud jaata hai.*p = 42— "pjo box name karta hai wahan jaao aur 42 store karo." Lekin woh box wall hai.
Step 1 se todne par exactly yahi tasveer milti hai.
Step 3 — Condition 3 todo: arrow block se aage nikal jaata hai (buffer overflow)
KYA. Arrow sahi block se shuru hota hai, lekin jo index hum add karte hain woh use aakhri box se aage, ek neighbouring variable mein push kar deta hai.
KYUN. C array apne saath koi length nahi rakhta. p[i] ko "p ka address + i boxes" ke roop mein calculate kiya jaata hai, bina kisi check ke ki i abhi bhi andar hai. Toh ek box aage likhna silently jo bhi agli cheez hai use overwrite kar deta hai — ek adjacent variable, ya (stack par) ek saved return address, jo classic exploit hai.
TASVEER. 
int a[5]; // valid boxes: a[0] .. a[4]
for (int i = 0; i <= 5; i++) a[i] = 0; // i==5 overshootsHar term:
a[5]— 5 boxes declare karta hai, indices .a[5]jaisa koi box nahi hai.i <= 5— loopi = 0,1,2,3,4,5run karta hai. Aakhri pass mein,a[5] = 0, neighbour mein likhta hai (figure mein amber "collision" box).- Fix:
i < 5har access ko ke andar rakhta hai jahan .
String version bhi wahi overshoot hai, hidden terminator ginte hue (dekho Strings in C and the null terminator):
Step 4 — Block marta hai: free(p) actually kya badalta hai
KYA. Hum free(p) call karte hain. Tasveer mein, block alive (cyan) se dead (grey hatch) ho jaata hai — lekin p ke andar ka arrow nahi hilta.
KYUN. Yeh poore page ka sabse important frame hai. free ek ordinary function hai jo address ki ek copy leta hai. Woh boxes allocator ko wapas karta hai, lekin woh vaapis nahi pahunch sakta aur tumhara variable p edit nahi kar sakta. Toh p ek aisi block par point karta rehta hai jo ab tumhari nahi — yeh dangling pointer hai.
TASVEER. 
free(p); // block → dead; p still holds the old addressHar term:
- Block boxes grey ho jaate hain: condition 2 ("block is alive") ab false hai.
- Amber arrow unchanged hai — yahi trap hai.
pabhi bhi un grey boxes ko naam deta hai.
Step 5 — Dead block ko touch karo: use-after-free
KYA. Step 4 ke baad, hum p ko anyway dereference karte hain.
KYUN. Condition 2 toot gayi hai. Step 2 ke honest crash se bhi bura: allocator un exact boxes ko agla malloc ke liye re-lend kar sakta hai. Tab p aur koi doosra pointer same boxes ko naam deta hai — p ke through likhna silently doosre variable ke data par scribble karta hai. Aksar crash nahi, sirf corruption.
TASVEER. 
free(p);
printf("%d\n", *p); // reads a dead (maybe reused) box*p— stale arrow ko grey/re-lent region mein follow karta hai.- Figure mein ek doosra arrow
q(baad kemallocse) same boxes par land hota dikhta hai: woh overlap corruption hai.
Step 6 — Dead block ko phir free karo: double free
KYA. Hum abhi bhi dangling p par free(p) doosri baar call karte hain.
KYUN. Allocator apni bookkeeping (block size, "next free block") inline rakhta hai, tumhara data ke bilkul paas. Pehle free ne is block ko apne records mein file kiya. Ise do baar file karna us internal list ko tangle karta hai — metadata corrupt karta hai jise ek attacker steer kar sakta hai, ya abort trigger karta hai.
TASVEER. 
free(p);
free(p); // second free tangles the allocator's list- Dono
freecalls same address carry karte hain (arrow Step 4 se unchanged). - Figure allocator ki "free-list" chain ko apne aap mein loop karte dikhata hai — yahi corruption hai.
Step 7 — Kabhi free nahi kiya: leak (aur conservation law)
KYA. Hum ek live block ka akela arrow, use free karne se pehle, overwrite kar dete hain. Block alive par unreachable rehta hai — koi pointer use naam nahi deta, toh ise kabhi free nahi kiya ja sakta.
KYUN. Kuch crash nahi hota. Block sirf wahan baitha rehta hai aur memory hamesha ke liye occupy karta rehta hai. Ek loop ya long-running server mein, yeh khoye hue blocks pile up hote hain jab tak machine thrash na kare ya OOM-killer na aaye. Yeh condition 1 ka ulta hai: arrow chala gaya, lekin block ruka raha.
TASVEER. 
char *p = malloc(100); // block A, 100 bytes
p = malloc(200); // arrow jumps to block B; A now unreachable
free(p); // frees only Bp = malloc(200)— arrow block A ko chhod kar block B par land karta hai.- Figure mein block A ka koi arrow nahi — woh orphan hai (amber "lost" tag). Woh leaked hai.
free(p)sirf B reclaim karta hai.
Tools jo yeh ledger tumhare liye watch karte hain: Valgrind and AddressSanitizer.
Ek-tasveer summary
KYA. Ek strip, ek lifetime, paanchon errors exactly us moment par pinned jab woh hote hain.

Block paida hota hai (malloc), jeeta hai, marta hai (free). Time axis ke saath har error ek galat touch hai:
- janam se pehle / ek failed janam par → arrow box #0 par → null deref
- zindagi ke dauran, edge ke aage → buffer overflow
- marne ke baad, touch karna → use-after-free
- marne ke baad, phir free karna → double free
- marne se pehle arrow kho dena → memory leak
Recall Feynman: seedhe alfaazon mein poora walkthrough
Ek rented locker (heap block) aur uske number wali ek sticky note (pointer) ki kalpana karo. malloc locker rent karta hai aur tumhari note par uska number likhta hai. Null deref: rental fail ho gaya, tumhari note "locker 0" — ek wall — kaehti hai — aur tum andar haath daalo aur wall se takrao (crash). Overflow: tumhara saamaan locker se bada hai, toh woh padosi ke andar spill ho jaata hai aur unki cheezein kharaab karta hai. Ab tum locker wapas karte ho (free) — lekin koi tumhari note erase nahi karta, abhi bhi wahi purana number dikhta hai. Use-after-free: tum ek aise locker mein haath daalo jo tumne already return kar diya; gym ne use re-rent kar diya hoga, toh tum ab kisi aur ke locker mein haath maar rahe ho. Double free: tum usi locker ko do baar return karne ki koshish karte ho aur front desk ki list jam kar dete ho. Leak: tum apni note par naya number scribble kar dete ho purana locker return karne se pehle — ab kisi ko pata nahi woh kahan hai, aur woh hamesha ke liye rent par hai. Cure ek matchbox par fit ho jaata hai: check karo ki rental kaam kiya, har locker ke liye ek note rakho, locker return karte hi note erase karo (yeh re-return aur wrong-reach dono ko harmless bana deta hai), aur har locker exactly ek baar return karo.