C++ - Smart Pointers in C++ (Modern Memory Management)

Smart pointers are RAII-based objects that manage dynamic memory automatically.
They prevent memory leaks and eliminate manual delete.

Defined in:

#include <memory>

Why Smart Pointers?

Traditional way:

int* p = new int(10);
delete p;  // programmer must remember

Problems:

  • Memory leaks

  • Double delete

  • Dangling pointers

  • Exception safety issues

Smart pointers solve this.


Types of Smart Pointers

There are 3 main types:

  1. std::unique_ptr

  2. std::shared_ptr

  3. std::weak_ptr


1) std::unique_ptr

Key Property:

  • Only one owner

  • Cannot be copied

  • Can be moved

Example:

#include <memory>
#include <iostream>

int main() {
    std::unique_ptr<int> p1 = std::make_unique<int>(10);

    // std::unique_ptr<int> p2 = p1;  ERROR (cannot copy)

    std::unique_ptr<int> p2 = std::move(p1); // transfer ownership

    std::cout << *p2;
}

After move:

  • p2 owns memory

  • p1 becomes nullptr

Use Case:

  • When ownership is exclusive

  • Best performance

  • Preferred by default


2) std::shared_ptr

Key Property:

  • Multiple owners allowed

  • Uses reference counting

Memory is deleted when count becomes 0.

Example:

#include <memory>
#include <iostream>

int main() {
    std::shared_ptr<int> p1 = std::make_shared<int>(100);
    std::shared_ptr<int> p2 = p1;  // shared ownership

    std::cout << p1.use_count(); // 2
}

When both p1 and p2 go out of scope → memory deleted.

Use Case:

  • Shared ownership model

  • Graphs, resource sharing systems


3) std::weak_ptr

Key Property:

  • Non-owning reference to shared_ptr

  • Does NOT increase reference count

  • Prevents circular dependency

Why needed?

Problem:

class A {
    std::shared_ptr<B> b;
};

class B {
    std::shared_ptr<A> a;
};

This creates circular reference → memory leak.

Solution:

std::weak_ptr<A> a;

To access:

if (auto temp = weakPtr.lock()) {
    // safe to use
}

Comparison Table

Feature unique_ptr shared_ptr weak_ptr
Ownership Single Multiple No ownership
Copy allowed No Yes Yes
Move allowed Yes Yes Yes
Reference counting No Yes No
Prevent circular ref Not needed No Yes

Important Rules

1. Prefer make_unique() and make_shared()

Safer and exception-friendly.

2. Avoid raw new and delete in modern C++

3. Use unique_ptr by default

Use shared_ptr only if ownership must be shared.


Performance Note

  • unique_ptr → fastest (no reference counting)

  • shared_ptr → slightly slower (atomic ref counting)

  • weak_ptr → lightweight observer


Interview-Level Understanding

Smart pointers implement RAII (Resource Acquisition Is Initialization):

  • Resource acquired in constructor

  • Automatically released in destructor

This ensures:

  • Exception safety

  • No memory leaks

  • Deterministic cleanup