Course outline · 0% complete

0/27 lessons0%

Course overview →

RAII: Why Modern C++ Rarely Writes delete

lesson 6-2 · ~11 min · 16/27

The problem with manual delete

Pairing every new with a delete sounds easy until real code intervenes:

void process() {
    int* buf = new int[1000];
    if (loadFailed()) return;   // oops: leaked, delete never runs
    // ... an exception here also skips the delete ...
    delete[] buf;
}

Every early return, break, or exception is a path that can skip the cleanup line. Chasing all paths by hand does not scale.

The C++ answer: RAII

RAII (Resource Acquisition Is Initialization) means: wrap the resource in an object, acquire it in the constructor (code that runs when the object is created), release it in the destructor (code that runs automatically when the object's scope ends). The language guarantees the destructor runs on every exit path.

Unit 7 teaches you to write constructors and destructors yourself. First, meet the standard library's ready-made RAII wrapper for heap memory.

std::unique_ptr

std::unique_ptr<T> (from <memory>) is a pointer-sized object that owns one heap allocation and deletes it in its destructor:

#include <memory>

void process() {
    auto buf = std::make_unique<int[]>(1000);  // heap array, owned
    buf[0] = 42;
    if (loadFailed()) return;   // fine: destructor frees it
}                               // fine: destructor frees it here too
  • std::make_unique<T>(args) allocates and wraps in one step. No raw new in sight.
  • Use it like a pointer: *p, p->member, or buf[i] for the array form.
  • auto asks the compiler to deduce the variable's type from the right-hand side, sparing you writing std::unique_ptr<int[]> out.
  • Unique means exactly one owner: a unique_ptr cannot be copied, only moved to a new owner with std::move.

The modern rule: new/delete are for understanding and for interviews about internals. In code you write, prefer unique_ptr, and even more often prefer containers like std::vector (unit 8), which are RAII wrappers around arrays.

Code exercise · cpp

Run this. The unique_ptr frees its int automatically, and the tiny Probe struct proves destructors run at scope exit: its message prints even though nobody calls anything at the end.

Quiz

Why is unique_ptr's cleanup more reliable than writing delete yourself?

Code exercise · cpp

Your turn. Rewrite this leaky raw-pointer code to use std::make_unique<int>(...) instead of new, and remove the (missing!) delete problem entirely. Output must stay `total: 30`.