Week 25 · Phase 3 — The Architect
Letting C++ manage memory for you — and the rule of "no raw new".
Photo · Jacob Elliott / Unsplash
Heap memory is the great unsolved problem of C. malloc and free, paired by hand, leaking when forgotten, double-freed when over-zealous. The whole reason garbage collection exists — Java, Python, Go — is to take that pairing off the programmer's plate at the cost of a runtime overseer.
C++ has a different answer. Three small RAII wrappers in <memory>, each with a clear ownership rule. Use them, and your heap leaks vanish at compile time, not runtime. The chef pays nothing extra.
std::unique_ptr — exclusive ownership"Exactly one place owns this object." When the unique_ptr goes out of scope, it deletes what it points at. You can move ownership to another unique_ptr, but you cannot copy it.
std::unique_ptr<Account> a = std::make_unique<Account>(42);
a->deposit(100); // use it like a pointer
// ... at end of scope, the Account is automatically deleted
std::unique_ptr<Account> b = a; // COMPILE ERROR: not copyable
std::unique_ptr<Account> b = std::move(a); // OK — ownership transferred to b; a is now empty
The compiler enforces single ownership. Trying to copy a unique_ptr fails to compile. Trying to use it after moving from it gives you a null pointer (and a tool warning). Cleaner than C, no overhead beyond a single pointer's worth of storage.
Use this 90% of the time. If you're not sure which smart pointer you need, start with unique_ptr.
std::shared_ptr — reference-counted shared ownership"Several places might own this; delete it when the last one lets go."
std::shared_ptr<Tensor> x = std::make_shared<Tensor>(1024);
std::shared_ptr<Tensor> y = x; // reference count: 2
// when both x and y go out of scope, count → 0, Tensor deleted
shared_ptr carries a reference count next to the object. Copies bump it; destructions decrement it. When the count hits zero, the object is freed.
It's not free: there's the cost of an atomic increment/decrement on every copy/destroy, plus the extra word for the count. For most code that's invisible. For high-throughput inner loops it shows up. Don't use shared_ptr by default; use it when ownership genuinely is shared. Lots of C++ codebases overuse it.
std::weak_ptr — observe without owningIf A owns B and B has a back-pointer to A, two shared_ptrs pointing at each other will never reach refcount zero — a cycle, and the equivalent of a leak. weak_ptr breaks the cycle: it observes a shared_ptr's object without contributing to its refcount.
Don't worry about weak_ptr until you have a cycle problem; you'll know.
new" ruleModern style: your code should never contain a raw new or delete. Every new hides immediately inside a make_unique or make_shared. Every heap allocation is owned by a smart pointer from the moment it exists. The class destructor handles the rest. The compiler enforces it.
The benefit isn't theoretical. The "use after free" / "double free" / "memory leak" bug categories — the ones responsible for half of every CVE filed against a C codebase — collectively become much harder to write in this style. They don't quite vanish (you can still misuse weak_ptr), but they get a great deal rarer.
Tensors in PyTorch are reference counted. at::Tensor is a shared_ptr-like handle to a TensorImpl. When Python copies a tensor variable, the C++ side bumps the refcount. When the last reference drops, the underlying GPU memory returns to the pool. The pattern scales — you can have a tensor referenced from twenty places without anyone tracking lifetimes by hand.
Same in TensorFlow's core, in ONNX Runtime, in JAX's XLA. Smart pointers are the load-bearing memory abstraction for every modern AI framework written in C++.
The keyword delete belongs in your past. Smart pointers belong in your future.
std::unique_ptr to it. Call methods through the smart pointer. Watch the destructor fire automatically when it goes out of scope.unique_ptr. Read the error. Try std::moveing it instead.shared_ptrs point at the same object. Print p.use_count() at various points and watch it go up and down.You've got the language. Time to meet the library that ships with it — and that almost every C++ project in existence depends on.
Week 26 is The STL — the Standard Template Library, with vectors, maps, sets, sorting, and the algorithms that come for free.
Photo free under the Unsplash license. Keys · Jacob Elliott.