5.2.13 · D5 · HinglishC++ Programming

Question bankRAII — resource acquisition is initialization — why it's the key idiom

2,027 words9 min read↑ Read in English

5.2.13 · D5 · Coding › C++ Programming › RAII — resource acquisition is initialization — why it's the


Do tasveerein jo dimaag mein rakhni hain

Traps se pehle, ye do images achhi tarah se yaad kar lo — neeche ke lagbhag har sawaal inhi mein se kisi ek ke baare mein hai.

Tasveer 1 — stack reverse order mein destroy karta hai (LIFO). Objects ek scope ke run hone par neeche se upar build hote hain; jab scope kisi bhi wajah se khatam hota hai, woh upar se neeche tear down hote hain. RAII isi guaranteed teardown par sawaar rehta hai.

Figure — RAII — resource acquisition is initialization — why it's the key idiom

Tasveer 2 — ek owner vs. shared ownership. Ek unique_ptr sole owner hota hai: exactly ek destructor resource free karta hai. Ek shared_ptr ek side "control block" mein reference count rakhta hai: sirf aakhri owner jo marta hai woh delete chalata hai. Yahi wajah hai ki ek copy-safe hai aur doosra copying forbid karta hai.

Figure — RAII — resource acquisition is initialization — why it's the key idiom

True ya false — justify karo

Har item "True ya False, aur batao kyun" hai. Sirf yes/no ka koi score nahi — justification hi sab kuch hai.

RAII ka naam accurately describe karta hai jo use powerful banata hai.
False. Power destructor mein hai (guaranteed release), initialization mein nahi — iska better naam hoga "Scope-Bound Resource Management". Destructor woh special member hai jo object ki life ke end mein chalta hai; dekho Constructors and Destructors.
Agar ek function mein koi throw statements nahi hain, toh RAII ka koi fayda nahi.
False. Koi bhi function jo yeh call karta hai throw kar sakta hai, aur exceptions ke bina bhi, multiple return/break paths har ek manual cleanup skip karte hain — RAII sirf exceptions nahi, sab exits cover karta hai.
Ek local object ka scope normal return, break, ya thrown exception se khatam hone par destructor run hona guaranteed hai.
True. Teeno stack unwinding (Tasveer 1 mein reverse-order teardown) ke zariye scope chodते hain, jo har local ka destructor chalata hai. Ek exception hai process-terminating path jaise std::exit(), std::abort(), ya std::terminate() — woh local destructors skip karte hain (Edge cases dekho). Dekho Stack Unwinding and Exceptions.
Ek raw new ko std::unique_ptr mein wrap karna double-free cause kar sakta hai agar aap pointer copy karo.
False. Ek unique_ptr (Tasveer 2 mein single-owner smart pointer) by design non-copyable hai; compiler copy reject karta hai, isliye double-free structurally impossible hai. Dekho Smart Pointers - unique_ptr shared_ptr.
Ek hi object par do shared_ptrs dono out of scope jaane par double-free karenge.
False. Ek shared_ptr reference count rakhta hai; har copy use bump up karti hai, har destruction use bump down karti hai, aur sirf aakhri owner (count → 0) delete chalata hai — exactly Tasveer 2 ka mechanism. Dekho Smart Pointers - unique_ptr shared_ptr.
std::vector<int> v(100) aur int* p = new int[100] equally leak-safe hain.
False. vector ka destructor buffer ko kisi bhi scope exit par automatically free karta hai; raw new[] ko matching delete[] chahiye jo exception ya early return skip kar sakta hai.
Local objects usi order mein destroy hote hain jis order mein construct hue the.
False. Woh reverse (LIFO) order mein destroy hote hain — Tasveer 1 mein upar-pointing arrow — taaki baad wala object safely un resources par depend kar sake jo pehle wale ne own kiye hain, jab tak dependent khud nahi chala jaata.
Ek RAII object se move karna aur phir source ko destroy hone dena resource ko do baar free karta hai.
False. Ek sahi move pointer steal karta hai aur source ka nullptr set karta hai; source ka destructor phir kuch nahi karta, "exactly one owner frees" sach rakhta hai. Ek move ownership copy karne ki jagah transfer karta hai; dekho Move Semantics.
Destructor ko noexcept banana sirf style preference hai.
False. Agar destructor stack unwinding ke dauran throw karta hai (jab doosri exception active ho), toh program std::terminate call karta hai — isliye destructors par noexcept (throw na karne ka promise) correctness requirement hai.

Error dhundho

Har line flawed code ya reasoning describe karti hai; reveal bug ka naam aur fix batata hai.

Widget* w = new Widget(); use(w); delete w; — isse kya toot ta hai?
Agar use(w) throw kare, delete w skip ho jaata hai → leak. Fix: auto w = std::make_unique<Widget>(); taaki destructor kisi bhi exit par free kare.
Ek class FILE* hold karti hai aur compiler-generated copy constructor par rely karti hai — kya galat hoga?
Default copy pointer value duplicate karta hai, do objects ko same handle deta hai → double fclose. Fix Rule of Five ke zariye (copy/move/destroy ka har moment control karo); dekho Rule of Three Five Zero.
m.lock(); risky(); m.unlock(); ek function ke andar — trap kya hai?
Agar risky() throw kare, unlock() kabhi nahi chalta → mutex hamesha ke liye locked rehta hai → deadlock. Fix: std::lock_guard<std::mutex> g(m);, ek guard jiska destructor automatically unlock karta hai. Dekho std::lock_guard and Mutexes.
Ek RAII owner ke destructor mein failed cleanup par throw std::runtime_error(...) — kyun forbidden hai?
Agar yeh doosri exception ke unwinding ke dauran fire ho, do exceptions in flight hain → std::terminate. Fix: error swallow ya log karo, destructor ko noexcept mark karo.
Ek function local std::string mein point karta const char* return karta hai, phir string out of scope jaati hai. Galti kya hai?
string ka buffer scope end par free ho jaata hai, isliye returned pointer dangle karta hai → use-after-free. Fix: value se return karo ya ownership transfer karo.
std::unique_ptr<int> a = b; jahan b doosra unique_ptr hai — kya yeh compile hoga?
Nahi — copy deleted hai. Aapko move karna hoga: std::unique_ptr<int> a = std::move(b);, jo ownership transfer karta hai aur b khali kar deta hai. Dekho Move Semantics.
Koi Rule-of-Five class likhta hai par copy-assignment mein purana resource release karna bhool jaata hai.
Object overwrite hone par purana owned resource leak ho jaata hai. Copy assignment release-then-acquire (ya copy-and-swap) karna chahiye. Dekho Rule of Three Five Zero.

Why questions

Resource ko ek stack object ke andar rakhna hi poora trick kyun hai, delete se careful rehne ki jagah?
Kyunki language guarantee karta hai ki stack objects ke destructors har exit path par chalte hain (Tasveer 1); "careful rehna" ek insaan par depend karta hai jo kabhi return/throw miss nahi karta, jo scale par fail hota hai.
Move semantics mein source pointer ko null karna kyun zaroori hai, sirf copy karne ki jagah?
Single-owner invariant preserve karne ke liye — agar dono pointers valid rehte, dono destructors same resource free karte → double-free. Dekho Move Semantics.
shared_ptr ko object mein raw count ki jagah alag control block kyun chahiye?
Count independently survive karna chahiye aur sab copies mein share hona chahiye (Tasveer 2 mein side box); use embed karna uski lifetime ko us object se bind kar deta jo usse manage karne ki koshish kar raha hai. Dekho Smart Pointers - unique_ptr shared_ptr.
Rule of Five "resource create, copy, ya destroy hone ke har moment control karne" ke baare mein kyun hai?
Agar aap un moments mein se koi bhi compiler default par chhod do, woh shallow pointer copy karta hai — silently ownership tod deta hai; invariant rakhne ke liye aapko sab paanch own karne chahiye. Dekho Rule of Three Five Zero.
RAII almost free mein "basic" aur "strong" exception-safety guarantee kyun deta hai?
Kyunki cleanup unwinding par automatic hai, exception propagate hone par koi resource leak nahi hota — guarantee scope-bound release ka consequence hai. Dekho Exception Safety Guarantees.
lock()/unlock() manually pair karne ki jagah std::lock_guard prefer kyun karein?
Guard ka destructor exceptions sameit kisi bhi exit par unlock karta hai, isliye aap kabhi critical section locked nahi chhod sakte. Dekho std::lock_guard and Mutexes.
"Rule of Zero" aksar best RAII advice kyun hai?
Agar aapki class sirf already-RAII members (smart pointers, vectors, strings) hold karti hai, toh aap koi special members nahi likhte — members khud clean ho jaate hain, aur koi hand-written destructor nahi hai jo galat ho sake. Dekho Rule of Three Five Zero.

Edge cases

Agar ek constructor ek resource acquire karne ke baad lekin finish hone se pehle throw kare, kya destructor clean up karne ke liye chalta hai?
Nahi — destructor sirf fully constructed objects ke liye chalta hai. Lekin already-constructed members destroy hote hain, aur exactly yahi wajah hai ki sub-resources khud RAII members hone chahiye. Dekho Constructors and Destructors.
Agar aap std::abort(), std::exit() call karo, ya process crash ho, toh RAII cleanup ka kya hota hai?
Local objects ke destructors nahi chalte — ye process ko bina normal stack unwinding ke terminate karte hain, isliye RAII ki guarantee apply nahi hoti aur OS-level cleanup (handles close karna) aapka ek hi sahara hai.
Kya normal thrown exception (jo catch ho jaata hai) destructors ko std::exit() ki tarah skip karta hai?
Nahi — thrown exception crash nahi hai. Jaise woh propagate karta hai, stack normally unwind karta hai, har local destructor chalata hai; sirf unhandled exception jo std::terminate tak pahunche, ya explicit std::abort()/std::exit(), unhe skip karta hai.
Ek unique_ptr default-construct hota hai aur kabhi resource assign nahi hota. Kya uska destructor trouble cause karta hai?
Nahi — yeh nullptr hold karta hai, aur delete nullptr well-defined no-op hai, isliye empty state perfectly safe hai.
Ek exception throw hoti hai jab stack already pehli exception se unwind ho raha hota hai — C++ kya karta hai?
Yeh std::terminate call karta hai; aapke paas do exceptions ek saath propagate nahi ho sakti, aur exactly yahi wajah hai ki destructors noexcept hone chahiye. Dekho Stack Unwinding and Exceptions.
Ek shared_ptr cycle (do objects ek doosre ko point karte hue) out of scope jaati hai. Kya woh free hote hain?
Nahi — har ek doosre ka count zero se upar rakhta hai, isliye koi count 0 tak nahi pahunchta → leak. Cycles weak_ptr se todein. Dekho Smart Pointers - unique_ptr shared_ptr.
Aap ek RAII object se move-construct karte ho aur phir moved-from source use karte ho. Kya yeh undefined behaviour hai?
UB nahi, lekin source valid-but-unspecified (usually empty/null) state mein hai; ise read karna legal hai, purani contents par rely karna bug hai. Dekho Move Semantics.
Ek global/static RAII object resource own karta hai — uska destructor kab chalta hai?
Program exit par, construction ke reverse order mein — lekin translation units mein ordering unspecified hai, isliye statics ke beech cross-dependencies fragile hain.
Recall Ek-line summary yaad rakhne ke liye

RAII isliye kaam karta hai kyunki ek stack object ka destructor guaranteed run hota hai jab bhi scope normally unwind hota hai; upar ke har trap ka matlab ya toh "kisine woh unwinding bypass ki (jaise std::exit/abort)" ya "kisine single-owner invariant todi."