JSTAcademy
0 XP
Dashboard
Crash Courses
Memory Management & Smart Pointers
45 min
PhD+185 XP
Crash Courses · PhD

Memory Management & Smart Pointers

RAII, unique_ptr, shared_ptr, and eliminating manual delete
45 min read+185 XP on completionCert: C++ Crash Course
Tap any word in the text below to start reading from there.

Memory Management & Smart Pointers

Manual Allocation (the old way — avoid)

int* p = new int(42);
// ... if an exception is thrown here, delete never runs
delete p;   // manual cleanup — easy to forget or double-delete

Problems with raw new/delete:

  • Forgetting delete → memory leak
  • delete-ing twice → undefined behaviour
  • Exceptions skipping delete → leak

RAII — The Solution

RAII ties resource lifetime to object lifetime:

class FileHandle {
    FILE* f;
public:
    FileHandle(const char* path) : f(fopen(path, "r")) {}
    ~FileHandle() { if (f) fclose(f); } // guaranteed cleanup
    FILE* get() { return f; }
};

When FileHandle goes out of scope (normally or via exception), the destructor closes the file.

unique_ptr — Single Ownership

#include <memory>

auto p = std::make_unique<int>(42); // prefer make_unique over new
std::cout << *p << std::endl;       // 42
// p is automatically deleted when it goes out of scope

// Transfer ownership with move
auto p2 = std::move(p);     // p is now nullptr
// *p would crash — p no longer owns the int

// In containers
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(5.0));
shapes.push_back(std::make_unique<Rectangle>(3.0, 4.0));

shared_ptr — Shared Ownership

auto a = std::make_shared<int>(42);
auto b = a; // both own the int; reference count = 2

std::cout << a.use_count() << std::endl; // 2

{
    auto c = a;               // count = 3
    std::cout << *c << std::endl;
}                             // c destroyed, count = 2

// Object deleted when a and b both go out of scope (count → 0)

weak_ptr — Breaking Cycles

struct Node {
    int value;
    std::shared_ptr<Node> next;
    std::weak_ptr<Node>   prev; // weak — does not own
};

If both next and prev were shared_ptr, two nodes pointing at each other would never be freed (circular reference). weak_ptr breaks the cycle.

Choosing the Right Pointer

TypeUse when
`unique_ptr`Single owner — default choice
`shared_ptr`Multiple owners need the same object
`weak_ptr`Observing a shared_ptr without ownership (breaks cycles)
Raw pointer `T*`Non-owning view only; never store in a container

Custom Deleters

auto file = std::unique_ptr<FILE, decltype(&fclose)>(
    fopen("data.txt", "r"), fclose
);
// file is closed automatically even if an exception is thrown
0%