5.1.15 · D2 · HinglishC Programming

Visual walkthroughMemory layout — text, data, BSS, heap, stack segments

2,379 words11 min read↑ Read in English

5.1.15 · D2 · Coding › C Programming › Memory layout — text, data, BSS, heap, stack segments


Step 0 — "Address" hota kya hai aakhir?

Baaki poora page is baare mein hai ki kaunse boxes mein kya hota hai. Bas itna hi. Har symbol jo hum use karte hain — Text, Data, BSS, Heap, Stack — yeh sirf is street ka ek named hissa hai.

Figure dekho: horizontal bar hi woh street hai. Har tick ke neeche jo number hai woh address hai. Ab hum ise left (low) se right (high) ki taraf fill karenge.


Step 1 — Code ko kahin toh rehna hoga: Text segment

KYA HAI. Pehla hissa, sabse low addresses par, compiled machine instructions hold karta hai — woh actual add, jump, load operations jo tumhara C code ban ke nikla. Hum ise Text segment kehte hain (confusingly, yahan "text" ka matlab code hai, words nahi).

KYUN HAI. CPU ko instructions ko read karna padta hai unhe run karne ke liye. Do facts Text ko uska apna segment banane par majboor karte hain:

  1. Instructions program ke run hone ke dauran kabhi nahi badalte, isliye is hisse ko read-only mark kiya jaata hai. Agar koi bug (ya virus) yahan likhne ki koshish kare, toh OS program ko khatam kar deta hai. Free mein safety.
  2. Agar ek hi program ki 100 copies chalein, code bilkul same hoga — toh OS ek read-only copy store karta hai aur saari 100 copies usse share karne deta hai. Memory bachti hai.

PICTURE. Figure mein, far left par blue block Text hai. Chhota sa lock icon dekho — read-only. Arrow dikhata hai CPU ka instruction pointer ussey read kar raha hai, kabhi write nahi.


Step 2 — Globals jinki real value hai: Data segment

KYA HAI. Text ke bilkul baad Data segment baithta hai. Yeh global aur static variables hold karta hai jo tumne non-zero value se initialize kiye hain.

KYUN HAI. Socho: Yahan symbol g_init ek global variable hai, aur = 5 uski initial value hai. Woh literal information hai — program ise runtime par invent nahi kar sakta, isliye ise disk par executable file mein likhna padta hai aur load time par RAM mein copy karna padta hai. Yeh "disk se real value carry karo" wali job exactly Data karti hai.

PICTURE. Orange block, Text ke bilkul upar. Usme humne g_init ke box ko already number ke saath draw kiya hai, file se seedha loaded.


Step 3 — Clever trick: zeros ko apna segment kyun milta hai (BSS)

KYA HAI. Agla hissa: BSS segment (naam ek historical abbreviation hai — ise bas ek label samjho). Yeh globals/statics hold karta hai jo uninitialized hain ya explicitly zero set hain.

KYUN HAI — yahi elegant part hai. Do globals compare karo:

  • a ki value information hai → ise disk par store karna padega (woh Data hai, Step 2).
  • b ki value bilkul bhi information nahi hai. Ek million zeros bhi sirf... zero hain.

Toh disk par zeros likhne ki jagah barbad karne ki bajay, BSS sirf ek sticky note store karta hai: Yahan har zero global ke bytes ka total count hai. Load time par OS yeh note padhta hai aur us RAM ko zero-fill karta hai. Result: ek global int big[1000000]; (4 MB zeros ka) tumhare .exe mein ~0 bytes add karta hai — sirf number badata hai.

PICTURE. Green block. Disk par yeh patla drawn hai (sirf note " bytes"); runtime par ek arrow ise uske full RAM size tak inflate karta hai, saare boxes dikhate hue.


Step 4 — Runtime requests upar grow karte hain: Heap

KYA HAI. BSS ke baad ek bada khali region shuru hota hai. Iske bottom se, Heap upar higher addresses ki taraf grow karta hai. Heap woh memory hai jo tum runtime par malloc/calloc/realloc se grab karte ho (dekho malloc, calloc, realloc and free).

KYUN upar grow karo, aur alag segment kyun? Compiler pehle se nahi jaanta tum kitni runtime memory chahoge — woh input par depend karta hai. Toh woh Data/BSS ki tarah koi fixed box reserve nahi kar sakta. Iske bajay ek movable frontier hoti hai: Har malloc program break ko higher address ki taraf push karta hai, khali region ka aur hissa claim karta hai. Yahan symbol sirf ek marker hai; OS brk/sbrk call karta hai ise move karne ke liye. Upar (Text se door) grow karne ka matlab hai heap middle emptiness mein expand hoti hai.

PICTURE. Khali region ke bottom se, ek orange arrow "program break" label ke saath upar push karta hai jab teen malloc blocks ek doosre ke upar stack hote hain, addresses badhte hue.


Step 5 — Function calls neeche grow karte hain: Stack

KYA HAI. Bilkul top (highest addresses) par Stack baitha hai. Jab bhi tum koi function call karte ho, ek naya stack frame (uske parameters, return address, aur local variables) stack par rakha jaata hai, aur stack neeche lower addresses ki taraf grow karta hai (dekho Stack frames and the calling convention).

KYUN neeche, heap ki taraf? Stack aur heap ek hi khali middle region share karte hain. Agar heap bottom se upar grow kare aur stack top se neeche grow kare, toh dono free gap mein se jaisa chahiye waise use kar sakte hain — pehle se koi fixed wall decide nahi ki gayi. Yahan frontier ek CPU register hai: Function call karna rsp se subtract karta hai (neeche grow karo, "push"); return karna add back karta hai (shrink, "pop"). Automatic — isliye locals function return hone par gayab ho jaate hain.

PICTURE. Top se, ek blue arrow "stack pointer" label ke saath neeche push karta hai; har function call pichle frame ke neeche ek frame add karta hai. Descending stack aur rising heap ke beech free gap hoti hai.


Step 6 — Collision case (degenerate / edge behaviour)

KYA HAI. Kya hoga agar heap upar badhti rahe aur stack neeche sinkta rahe jab tak woh mil na jaayein?

KYUN MAHATVAPOORN HAI. Woh gap share karte hain, toh extreme cases mein frontiers collide kar sakti hain:

  • Stack overflow — bahut deep recursion ya ek bada local array stack pointer ko uski limit se aage (forbidden territory mein) neeche drive kar deta hai. OS program ko maar deta hai.
  • Heap exhaustionmalloc program break ko aage move nahi kar sakta, toh woh special "failed" pointer return karta hai:

Yeh alag segments mein alag failures hain — inhe kabhi confuse mat karo.

PICTURE. Gap zero ho jaati hai; ek red flash collision mark karta hai, dono culprit arrows label ke saath.


Step 7 — Ek real program ko map par rakhna

KYA HAI. Ab ek chhote program ke har variable ko us street par rakh do jo humne abhi banaayi.

int   g_init = 5;       // (A)
int   g_zero = 0;       // (B)
int   g_uninit;         // (C)
int main(void) {
    int local = 3;      // (D)
    static int s = 0;   // (E)
    int *p = malloc(40);// (F) pointer p aur uska 40-byte block
}

KYA HAR EK WAHAN KYUN LAND KARTA HAI (Steps 2–5 ke rules apply karo):

Var Segment Ek deciding fact
A g_init=5 Data global aur non-zero init → value disk par stored
B g_zero=0 BSS global, zero → sirf ek "reserve, zero-fill" note
C g_uninit BSS uninitialized global = zero jaisa treat hota hai
D local=3 Stack main ke frame mein auto variable
E s=0 BSS static = static storage, zero → BSS (Stack nahi!)
F p Stack pointer variable ek local hai
F *p (40 B) Heap malloc heap memory return karta hai

Subtle wale — (E) ek static local stack par nahi hota (woh poore program mein rehta hai, isliye global rules follow karta hai → BSS kyunki zero hai); aur (F) pointer p aur jo block woh point karta hai woh do alag segments mein rehte hain. Dekho Static and global variables — storage duration.

PICTURE. Har variable ek labelled box ki tarah apne correct segment mein drawn hai, (F) ka pointer stack par aur ek arrow heap block ki taraf neeche jaata hua.


Ek-picture summary

Yeh single figure sab kuch compress karta hai: low→high addresses left to right; Text (read-only code), Data (non-zero globals, real values on disk), BSS (zero globals, sirf ek size note), phir shared khali region jisme Heap bottom se rise karti hai (program break, malloc) aur Stack top se sink karta hai (stack pointer, function calls), sirf extreme mein collide karte hue.

Recall Feynman retelling — poora walkthrough simple words mein

Tumhare program ko numbered boxes ki ek lambi street milti hai. Low-number end par hum instruction manual — Text — bolt karte hain aur lock kar dete hain taaki koi uspar scribble na kare. Uske bilkul upar hum woh toys rakhte hain jo pre-filled aayi hain — Data — kyunki ek 5 real cheez hai jo hum disk se carry karke laaye the. Phir aate hain khale boxes ek sticky note ke saath "reserve karo N, zeros se fill karo" — BSS — taaki hum moving truck mein ek million zeros nahi dhaote. Poora middle khala floor hai: bottom se, toy pile upar grow karti hai jab bhi tum malloc bolte ho (woh top edge program break hai), aur ceiling se, plates ka stack neeche grow karta hai jab bhi tum koi kaam/function shuru karte ho (woh edge stack pointer hai, aur kaam khatam karna plate wapas le jaata hai automatically). Woh tab hi crash karte hain jab pile aur plates mil jaayein — stack overflow ya malloc ka NULL return karna. Finally, koi bhi variable place karne ke liye: kya woh global/static hai? non-zero → Data, zero → BSS. Kya woh plain local hai? → Stack. Kya malloc ne banaya? → Heap (lekin uski taraf pointer abhi bhi Stack par ek local hai).

Recall Rapid self-test

Read-only segment? ::: Text. int x = 5; global kahan rehta hai? ::: Data. int x = 0; global kahan rehta hai? ::: BSS. static int s = 0; kisi function ke andar? ::: BSS (static storage, zero). int *p = malloc(40); mein pointer p? ::: Stack. p jis 40-byte block ko point karta hai? ::: Heap. Heap ko kaunsi frontier move karti hai? ::: Program break (upar grow karta hai). Stack ko kaunsi frontier move karti hai? ::: Stack pointer / rsp (neeche grow karta hai). malloc fail ho gaya — kya return karta hai? ::: NULL.


Connections

  • malloc, calloc, realloc and free — heap frontier kaise move hoti hai.
  • Stack frames and the calling convention — har downward-growing frame mein kya hota hai.
  • Static and global variables — storage duration — Data-vs-BSS deciding rule.
  • Pointers and dangling pointers — pointer-on-stack / block-on-heap split galat ho jaaye toh.
  • Virtual memory and paging — yeh segments physical RAM se kaise map hote hain.
  • Buffer overflow and stack smashing — kya hota hai jab stack apne frame ke baad likhaa jaaye.