Systems CourseC/C++ · Linux · Memory
C++ CoreLesson 40 of 442 min read8 questions

Smart Pointers

RAII wrappers that own a heap object and delete it automatically.

Test yourself ↓

Concept core idea Watch out easy to get wrong

Concept

Key concepts

  1. Smart pointers (in <memory>) are RAII wrappers around a raw pointer: they own the heap object and auto-delete it when they go out of scope — no manual delete, leaks, or dangling.
  2. unique_ptr = sole owner; can't be copied, only moved (std::move); near-zero overhead. Your default. Create with make_unique.
  3. shared_ptr = shared ownership via a reference count; the object is deleted when the count hits 0 (use_count()). Create with make_shared (one allocation). Has a control-block overhead.
  4. weak_ptr = non-owning observer of a shared_ptr; does NOT change the count. Used to break circular references and to check/access via .lock() (or .expired()). (Deep dive: the shared_ptr circular reference page linked at the bottom of this lesson.)
  5. Prefer make_unique/make_shared over raw new (exception-safe, no raw new). Smart pointers overload * and ->, so you use them like raw pointers.
  6. Members: .get() (raw pointer — don't delete), .reset() (delete now), unique_ptr::release() (give up ownership WITHOUT deleting — you must delete). Use raw pointers/references only for non-owning borrowing.

Creating, moving, sharing, observing

C++
#include <memory>

auto u = std::make_unique<Entity>();   // sole owner
auto v = std::move(u);                 // ownership moved; u is now nullptr

auto s  = std::make_shared<Entity>();  // use_count() == 1
auto s2 = s;                           // use_count() == 2 (shared)
std::weak_ptr<Entity> w = s;           // observes, does NOT bump the count
if (auto sp = w.lock()) { /* alive -> use sp */ }

v->method();   // smart pointers use -> and * like raw pointers
Deep dive

Go deeper

Watch out

Easily confused

unique_ptr vs shared_ptr
unique = one owner, move-only, no overhead. shared = many owners, ref-counted, deleted at count 0 (has a control block).
weak_ptr vs shared_ptr
shared owns and counts. weak observes without counting — breaks cycles; use .lock() to access safely.
release() vs reset() vs move
release() = give up ownership, NO delete (you must delete). reset() = delete now. move = transfer to another smart pointer.
owning vs non-owning
Smart pointers express ownership. Raw pointers/references are for borrowing — never delete through them.

Test yourself

8 questions on this lesson. Write your answers from memory, then compare them with the model answers side by side.