Language 2 of 10 · Topic 0.8

Memory Foundations: Smart Pointers (std::unique_ptr, std::shared_ptr, std::weak_ptr)

1Concept

Modern C++ eliminates raw memory management with Smart Pointers: 1. std::unique_ptr: Exclusive ownership (zero overhead over raw pointer), non-copyable, movable. 2. std::shared_ptr: Shared reference-counted ownership. 3. std::weak_ptr: Non-owning observer that breaks circular reference memory leaks.

2Architecture Diagram

unique_ptr<T>      ──► [ Sole Owner of Heap Object ] (Deletes on scope exit)

shared_ptr<T> #1 ──┐
shared_ptr<T> #2 ──┴─► [ Control Block: RefCount = 2 ] ──► [ Heap Object ]
                           (Deletes when RefCount reaches 0)

3Code Example

Stage 0 Language Foundations
#include <iostream>
#include <memory>

class ServiceNode {
public:
    std::string name;
    ServiceNode(std::string n) : name(n) {
        std::cout << "ServiceNode [" << name << "] Created\n";
    }
    ~ServiceNode() {
        std::cout << "ServiceNode [" << name << "] Destroyed (Freed!)\n";
    }
};

int main() {
    std::cout << "=== unique_ptr Exclusive Ownership ===\n";
    {
        auto u_ptr = std::make_unique<ServiceNode>("Payment-Gateway");
        std::cout << "Using node: " << u_ptr->name << "\n";
        // Memory automatically freed when scope ends!
    }

    std::cout << "\n=== shared_ptr Reference Counting ===\n";
    {
        auto s1 = std::make_shared<ServiceNode>("Auth-Cluster");
        std::cout << "RefCount: " << s1.use_count() << "\n";
        {
            auto s2 = s1; // Shared ownership
            std::cout << "RefCount after copy: " << s1.use_count() << "\n";
        } // s2 goes out of scope
        std::cout << "RefCount after inner exit: " << s1.use_count() << "\n";
    } // s1 goes out of scope, refcount = 0, node freed!

    return 0;
}

4Expected Output

=== unique_ptr Exclusive Ownership ===
ServiceNode [Payment-Gateway] Created
Using node: Payment-Gateway
ServiceNode [Payment-Gateway] Destroyed (Freed!)

=== shared_ptr Reference Counting ===
ServiceNode [Auth-Cluster] Created
RefCount: 1
RefCount after copy: 2
RefCount after inner exit: 1
ServiceNode [Auth-Cluster] Destroyed (Freed!)

5Key Takeaways

  • Default to std::unique_ptr for exclusive ownership (zero runtime overhead).
  • Use std::make_unique and std::make_shared instead of raw new.
  • Use std::weak_ptr for parent/child cycles to prevent circular memory leaks.