5.1.24 · D4 · HinglishC Programming

ExercisesUnions — overlapping memory

2,434 words11 min read↑ Read in English

5.1.24 · D4 · Coding › C Programming › Unions — overlapping memory

Poore document mein, jab tak koi problem alag na kahe, yeh assume karo:

  • char = 1 byte, short = 2 bytes, int = 4 bytes, float = 4 bytes, double = 8 bytes, aur ek pointer = 8 bytes (ek typical 64-bit machine).
  • Kisi type ki alignment = us type ka size in basic types ke liye (toh ek double chahta hai ki uska address 8 ka multiple ho).
  • Little-endian byte order (lowest-value byte sabse low address par store hota hai) jab tak alag na bataya jaaye. Dekho Endianness — byte order.
Figure — Unions — overlapping memory

Upar wali figure almost har answer ke peechhe ka mental model hai: saare members byte 0 se overlap karte hain, aur total width sabse bada member hota hai (alignment ke liye round up karke).


Level 1 — Recognition

(Kya tum rule bata sakte ho aur definition se padh sakte ho?)

L1.1

Ek sentence mein batao ki union ka har member memory mein kahan se shuru hota hai.

Recall Solution

Har member same address, offset 0 se shuru hota hai. Woh physically overlap karte hain — har member ke liye alag space nahi hoti (woh toh ek struct hoti).

L1.2

Is ke liye

union A { char c; short s; int i; };

sizeof(union A) batao.

Recall Solution

Sizes hain char=1, short=2, int=4. WHY largest? Room mein jo bhi member store ho usse fit karna zaroori hai, toh worst case — int — fit hona chahiye. Largest = 4, aur 4 pehle se hi int ki alignment (4) ka multiple hai.

L1.3

True ya false: ek union mein ek member likhne ke baad tum sab members ek saath padh sakte ho.

Recall Solution

False. Sirf woh member jisko tum last likhte ho meaningful data rakhta hai. Koi doosra member padhna matlab same bytes ko alag tarike se interpret karna — usually garbage. Deliberately ek alag member padhna type punning hai, "sab ko padhna" nahi.


Level 2 — Application

(Size aur offset rules ko concrete layouts par apply karo.)

L2.1

sizeof compute karo

union B { char c[10]; int i; double d; };
Recall Solution

Member sizes: char c[10] = 10, int = 4, double = 8. Sabse bada raw size = 10 (array). WHY alignment yahaan matter karti hai: strictest member double hai, alignment 8. Size ko 8 ke multiple tak upar round karna zaroori hai taaki in unions ke array mein har double 8-aligned rahe. Toh bhale hi sabse bada member 10 bytes ka hai, union 16 bytes ki hai.

L2.2

union C { unsigned char b[4]; int i; };
union C u;
u.i = 65;

Little-endian par, char bytes u.b[0..3] hex mein list karo, aur u.b[0] ko ek character ki tarah do.

Recall Solution

. Little-endian lowest-value byte pehle store karta hai: ASCII 0x41 hai 'A', toh u.b[0] print karta hai A.

L2.3

Same union, same u.i = 65, lekin ab machine big-endian hai. u.b[0] do.

Recall Solution

Big-endian highest-value byte pehle store karta hai: Toh u.b[0] hai 0x00 (NUL character), 'A' nahi. Yahi reason hai ki L2.2 wala character trick endianness-dependent hai.


Level 3 — Analysis

(Trace karo ki bits reinterpret hone par actually kya bante hain.)

L3.1

union D { int i; float f; } d;
d.f = 2.0f;
printf("%d", d.i);   // ?

Print hone wale integer ka prediction karo. IEEE-754 single precision use karo.

Recall Solution

WHY sirf "2" nahi? d.i padhna d.f likhne ke baad koi arithmetic conversion nahi karta — yeh raw float bit pattern ko ek integer ki tarah padhta hai. ke liye IEEE-754 bits: sign , exponent field (biased: ), mantissa . Assemble karo: Integer ki tarah woh hai . Toh yeh print karta hai 1073741824, 2 nahi.

L3.2

Ulta: integer 1078530011 ke exact same 4-byte pattern wali float value kaun si hai?

Recall Solution

. IEEE-754 ki tarah decode karo:

  • sign
  • exponent field actual exponent
  • mantissa bits , fraction deta hai, toh significand

Yeh well-known " ke float bits" hai. Yeh demonstrate karta hai ki union sirf bytes ko relabel karta hai — number ka meaning member ke saath completely badal jaata hai jo tum padhte ho.

L3.3

union E { short s; unsigned char b[2]; } e;
e.b[0] = 0x34;
e.b[1] = 0x12;
printf("%x", e.s & 0xFFFF);   // little-endian

Kya print hoga?

Recall Solution

Little-endian value ko (high byte << 8) | low byte ki tarah assemble karta hai, jahan low byte b[0] hai: 1234 print hoga. Note karo ki humne bytes "ulte" likhe (34 phir 12) taaki number 0x1234 mile — woh reversal hi little-endianness hai.


Level 4 — Synthesis

(Khud layouts aur safe patterns design karo.)

L4.1

Ek struct RGBA design karo jo ek single uint32_t par overlay ho taaki tum poore color ko ek 32-bit number ki tarah aur uske char channels r,g,b,a individually access kar sako. Little-endian assume karo, r lowest byte par. Union likho.

Recall Solution
union Color {
    unsigned int rgba;              // poori 32-bit value
    struct { unsigned char r, g, b, a; } ch;  // char channels
};

WHY union ke andar struct? Char channels simultaneously rehne chahiye (woh alag bytes hain), toh unhe separate memory chahiye — woh struct hai. Lekin woh poora 4-byte struct unsigned int se overlap karta hai, toh dono views same bytes share karte hain. Little-endian par, ch.r byte 0 hai = rgba ke lowest 8 bits. Toh rgba = 0x11223344 deta hai ch.r = 0x44, ch.g = 0x33, ch.b = 0x22, ch.a = 0x11.

L4.2

Ek tagged union Number banao jo ya toh 64-bit integer ya double hold kar sake, aur ek function print_number likho jo sirf active member padhta ho. Explain karo kyun tag zaroori hai.

Recall Solution
struct Number {
    enum { NUM_INT, NUM_DBL } tag;   // kaun live hai?
    union { long long i; double d; } val;
};
 
void print_number(struct Number n) {
    if (n.tag == NUM_INT) printf("%lld\n", n.val.i);
    else                  printf("%f\n",   n.val.d);
}

WHY tag? Union ke paas koi runtime memory nahi ki kaun sa member last likha gaya tha. enum tag tumhari bookkeeping hai taaki print_number sirf wahi member padhe jo actually store tha; doosra padhna unrelated bits ko reinterpret karta. Parent note mein tagged-union pattern dekho.

L4.3

L4.1 wale struct Number (tagged wala) ka sizeof do aur padding explain karo.

Recall Solution

Union { long long i; double d; } 8 bytes ki hai (dono members 8 hain, alignment 8). enum ek int = 4 bytes hai. Layout: tag offset 0 par (4 bytes), phir union ko 8-byte alignment chahiye, toh 4 bytes padding insert hoti hai, phir union offset 8 par. Poore struct ki alignment 8 hai (union ki wajah se), aur 16 pehle se 8 ka multiple hai, toh koi trailing padding nahi. Dekho Memory alignment and padding.


Level 5 — Mastery

(Edge cases, degenerate inputs, aur alignment ke under reasoning.)

L5.1

Exactly ek member wali union union U { double d; } ka sizeof kya hai? Aur agar (hypothetically) union ke zero members hote toh size kya hota?

Recall Solution

Ek member: size = woh member = sizeof(double) = 8. Ek lodger ke saath "sum vs largest" ki koi ambiguity nahi. Zero members: empty union standard C mein valid nahi — union mein kam se kam ek named member hona chahiye. (Kuch compilers ise extension ke taur par allow karte hain size 0 ya 1 ke saath, lekin uss par rely mat karo.)

L5.2

union F { char c; int i; };
union F u;
u.c = 'X';
printf("%d", u.i);   // ?

Precisely explain karo kyun printed integer unspecified hai, bhale hi humne kuch likha tha.

Recall Solution

Humne sirf 1 byte likha (u.c), lekin u.i padhna 4 bytes padhta hai. Byte 0 hai 'X' = 0x58; baaki 3 bytes kabhi nahi likhe gaye, toh woh memory mein indeterminate ("garbage") values rakhte hain. Isliye u.i koi number hai 0x??????58 (little-endian) ki tarah jahan ? bytes unknown hain. Result unspecified hai — sirf wahi byte reliably set hai jo u.c ne touch ki. Kabhi bhi uss member se wider member mat padho jise tumne initialize kiya tha.

L5.3

union G { char c[3]; short s; };  // char[3] = 3 bytes, short = 2, align(short)=2

sizeof(union G) compute karo aur alignment ke saath justify karo.

Recall Solution

Raw sizes: c[3] = 3, short = 2. Sabse bada raw = 3. Strictest alignment = short ki = 2. 3 ko 2 ke agle multiple tak round up karo: Toh union 4 bytes ki hai, 3 nahi — 1 byte padding add ki jaati hai taaki union G ke arrays mein har short even address par rahe.

L5.4

Is union mein jab double store ho tab byte layout (offsets) sketch karo union H { char tag; double d; };. Uska size kya hai, aur tag d ke relative kahan baithta hai?

Recall Solution

Dono members offset 0 se shuru hote hain — woh overlap karte hain. Toh tag aur d ka byte 0 same byte hai. d store karna tag overwrite karta hai; tag store karna d ka low byte corrupt karta hai. Size = sabse bada member double = 8, alignment 8, aur 8 pehle se 8 ka multiple hai, toh: Struct se key contrast: ek struct H mein dono alag offsets par hote (0 aur 8, padding ke saath), total 16 bytes; union mein woh offset 0 share karte hain aur 8 lete hain. Unions ka yahi memory-saving point hai.


Recall Quick self-check (cloze)

Union ke saare members offset 0 se shuru hote hain. Union ka size uske largest member ke barabar hota hai, alignment ke liye round up karke. Woh member padhna jo tumne nahi likha tumhe reinterpreted / garbage bits deta hai, converted value nahi. Ek tagged union union ko ek enum ke saath pair karta hai jo live member record karta hai.

Connections

  • Unions — overlapping memory (parent)
  • Structs — separate memory for each member
  • Memory alignment and padding
  • Endianness — byte order
  • Type punning and bit-level reinterpretation
  • Enums
  • sizeof operator