The Runtime Theory
C++

RAII and Smart Pointers

How Resource Acquisition Is Initialization prevents memory leaks, and how unique_ptr, shared_ptr, and weak_ptr manage ownership.

The Runtime Theory Team1 min read
▸ On this page

RAII and Smart Pointers

Manual memory management with new and delete is error-prone. RAII (Resource Acquisition Is Initialization) is a C++ idiom that makes resource management safe by tying it to object lifetimes.

RAII: Resource Acquisition Is Initialization

The core idea: when a resource is acquired (memory, file, lock), wrap it in an object whose destructor releases the resource. When the object goes out of scope — whether by normal return, early return, or exception — the destructor runs automatically.

cpp
{
  std::unique_ptr<int> p = std::make_unique<int>(42);
  // Memory is automatically freed when p goes out of scope
}

Smart Pointers

std::unique_ptr — Exclusive Ownership

cpp
auto p = std::make_unique<int>(42);
// p owns the memory — no other pointer can own it
// p2 = p;        // ❌ compilation error — no copy
auto p2 = std::move(p);  // ✅ transfers ownership
// p is now nullptr

std::shared_ptr — Shared Ownership

cpp
auto p = std::make_shared<int>(42);
auto p2 = p;  // both share ownership
// Reference count is now 2
// When p2 goes out of scope, count drops to 1
// When the last owner goes out of scope, memory is freed

std::weak_ptr — Non-owning Observer

cpp
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared;  // observes but doesn't own
 
if (auto locked = weak.lock()) {  // check if still alive
  std::cout << *locked << "\n";   // safe to use
}

When to Use Each

PointerUse when
std::unique_ptrOnly one owner. Prefer this for almost all cases.
std::shared_ptrMultiple owners, lifetime is unpredictable.
std::weak_ptrObserving a shared_ptr without extending its lifetime (avoids cycles).

Common Pitfalls

  1. Mixing new/delete with smart pointers — don't new a unique_ptr:

    cpp
    std::unique_ptr<int> p(new int(42));  // ❌ — exception safety issue
    auto p = std::make_unique<int>(42);   // ✅
  2. Circular references — two shared_ptrs pointing at each other never get freed:

    cpp
    struct Node {
      std::shared_ptr<Node> next;
      std::weak_ptr<Node> prev;  // ✅ use weak_ptr to break the cycle
    };
  3. Returning raw pointers from unique_ptr functions — always return the smart pointer, not a raw pointer.

Not started

Sign in to save your learning progress.

Sign in to save