5.2.12C++ Programming

Smart pointers — unique_ptr (sole ownership), shared_ptr (shared ownership, ref count), weak_ptr (break cycles)

2,221 words10 min readdifficulty · medium4 backlinks

1. The problem we are solving


2. unique_ptr — sole ownership


3. shared_ptr — shared ownership via reference count


4. weak_ptr — break reference cycles

Figure — Smart pointers — unique_ptr (sole ownership), shared_ptr (shared ownership, ref count), weak_ptr (break cycles)

5. Choosing the right one (the 80/20)



Recall Feynman: explain to a 12-year-old

Imagine a library book. A unique_ptr is a book only you can hold — when you leave, the book is returned automatically. You can hand it to a friend (move), but then you don't have it anymore. A shared_ptr is a popular book with a little tally sheet: every person borrowing adds a tick, everyone returning removes one. When the ticks hit zero, the book goes back on the shelf (deleted). A weak_ptr is a person who just wrote down where the book is, but didn't actually borrow it — they don't add a tick. Before reading it, they must check "is the book still here?" (lock()). The weak person stops two friends from accidentally keeping a book forever just by pointing at each other (a cycle).


Flashcards

What does unique_ptr guarantee about ownership?
Exactly one owner; it is non-copyable, only movable (ownership transfers, never duplicates).
Why is unique_ptr non-copyable?
Two copies would both delete the same object → double-free; copy ctor is =deleted, so you must std::move.
What does make_unique / make_shared give you over new?
No raw new, exception safety; make_shared also does a single allocation for object + control block.
What does a shared_ptr store?
A pointer to the object plus a pointer to a control block holding the strong count, weak count, and deleter.
When is a shared_ptr-managed object deleted?
When the strong (owner) count reaches 0; the control block frees when strong0 AND weak0.
What happens to use_count() when you copy a shared_ptr?
It increases by 1; it decreases by 1 when a copy is destroyed or reset.
What problem does weak_ptr solve?
Reference cycles — two shared_ptrs pointing at each other never reach count 0 and leak; weak_ptr observes without raising the strong count.
How do you safely access the object behind a weak_ptr?
Call lock(); it returns a shared_ptr if still alive, or an empty one if expired.
Does weak_ptr increase the strong reference count?
No — it only affects the weak count, so it never keeps the object alive.
Default smart pointer to reach for?
unique_ptr — cheapest and clearest; upgrade to shared_ptr only when ownership is truly shared.
Why is constructing two shared_ptrs from the same raw pointer a bug?
They create separate control blocks → each thinks it's sole owner → double-free.

Connections

  • RAII — the principle smart pointers implement (lifetime = scope).
  • Move-semantics — why unique_ptr transfers via std::move.
  • Rule-of-Zero — using smart pointers means you rarely write destructors.
  • Memory-leaks-and-dangling-pointers — the bugs these prevent.
  • Reference-counting — the algorithm inside shared_ptr.
  • Garbage-collection — contrast: deterministic destruction vs GC.

Concept Map

forgets delete

destructor calls delete

solved by

sole owner

shared owners

non-owning

non-copyable so use

created by

tracks

reaches zero

observes

breaks

Raw pointer T*

Memory leaks and bugs

RAII lifetime = scope

Smart pointers

unique_ptr

shared_ptr

weak_ptr

std::move transfers ownership

make_unique

reference count

object deleted

reference cycles

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, raw pointer (T*) sirf ek address hota hai — woh batata hai cheez kahaan hai, par ye nahi batata ki uska owner kaun hai aur delete kab karna hai. Isliye humein khud delete likhna padta hai, aur agar beech mein koi return ya throw aa gaya toh memory leak ho jaati hai. Smart pointer ek chhota object hai jo raw pointer ko wrap karta hai aur jab woh object scope se bahar jaata hai, uska destructor automatically delete chala deta hai. Yahi RAII ka funda hai.

unique_ptr ka matlab hai akela maalik — sirf ek owner. Isko copy nahi kar sakte (warna double-free crash ho jaaye), sirf std::move se ownership transfer kar sakte ho. Yeh sabse sasta aur clear hai, isliye default yahi use karo. shared_ptr tab use karo jab sach mein kai log ek hi object share kar rahe ho — yeh ek reference count rakhta hai: har copy par +1, har destruction par −1, aur jab count zero ho jaaye tab object delete. Hamesha make_shared use karo kyunki woh ek hi allocation mein object aur control block dono bana deta hai.

weak_ptr ka kaam hai cycle todna. Maan lo A, B ko shared_ptr se pakadta hai aur B, A ko — toh dono ek dusre ki count 1 par rakh dete hain, kabhi 0 nahi hoti, dono leak. Solution: ek direction ko weak_ptr bana do — woh observe karta hai par count nahi badhata, toh object alive nahi rakhta. weak_ptr ko seedha * se access nahi karte; pehle lock() karo, agar object zinda hai toh shared_ptr milega, warna empty — bilkul safe. Yaad rakho: U-S-W — Unique single owner, Shared with counter, Weak sirf watch.

Go deeper — visual, from zero

Test yourself — C++ Programming

Connections