Smart Pointers in C++

Last Updated : 19 Jan, 2026

A smart pointer is a class that wraps a raw pointer and automatically manages the lifetime of dynamically allocated memory.

  • It ensures proper resource deallocation by automatically releasing the memory when the pointer goes out of scope, thus preventing memory leaks and dangling pointers.
  • Smart pointers are defined in the <memory> header and include types such as std::unique_ptr, std::shared_ptr, and std::weak_ptr.

Problem with Raw Pointers (Memory Leak Example)

C++
#include <iostream>
using namespace std;

int main() {
    while (1) {
        int* ptr = new int;
    }
    return 0;
}

Explanation:

  • Memory is allocated repeatedly using new.
  • The allocated memory is never released using delete.
  • This results in a memory leak, eventually exhausting system memory.

Types of Smart Pointers

1. auto_ptr (Deprecated)

auto_ptr was an early smart pointer that automatically deleted the managed object when it went out of scope.

auto_pointer_in_c_
Auto Pointers in C++
C++
#include <iostream>
#include <memory>
using namespace std;

int main() {
    auto_ptr<int> ptr1(new int(10));
    cout << *ptr1 << endl;

    auto_ptr<int> ptr2 = ptr1;  // ownership transfer
    cout << *ptr2;
    return 0;
}

Output
10
10

Key Points:

  • Ownership is transferred, leaving the original pointer invalid.
  • Copy semantics are unsafe and error-prone.

Note: auto_ptr is deprecated after C++11 and it remove after C++ version 17.

2. unique_ptr

unique_ptr stores one pointer only at a time. We cannot copy unique_ptr, only transfer ownership of the object to another unique_ptr using the move() method.

unique-pointer-in-cpp
C++
#include <iostream>
#include <memory>
using namespace std;

class Rectangle {
    int length, breadth;

public:
    Rectangle(int l, int b) : length(l), breadth(b) {}
    int area() { return length * breadth; }
};

int main() {
    unique_ptr<Rectangle> P1(new Rectangle(10, 5));
    cout << P1->area() << endl;

    unique_ptr<Rectangle> P2;
    P2 = move(P1);  // ownership transfer

    cout << P2->area();
    return 0;
}

Output
50
50

Key Points

  • Only one unique_ptr can own an object at a time.
  • Lightweight and efficient.
  • Ideal for single ownership scenarios.

3. shared_ptr

shared_ptr allows multiple pointers to share ownership of the same object. It uses reference counting to manage memory.

shared-pointer-in-cpp
C++
#include <iostream>
#include <memory>
using namespace std;

class Rectangle {
    int length, breadth;

public:
    Rectangle(int l, int b) : length(l), breadth(b) {}
    int area() { return length * breadth; }
};

int main() {
    shared_ptr<Rectangle> P1(new Rectangle(10, 5));
    shared_ptr<Rectangle> P2 = P1;

    cout << P1->area() << endl;
    cout << P2->area() << endl;
    cout << P1.use_count();
    return 0;
}

Output
50
50
2

4. weak_ptr

weak_ptr is a non-owning smart pointer used with shared_ptr to prevent circular dependencies.

Key Characteristics

  • Does not increase reference count
  • Prevents circular dependency
  • Must be converted using lock() before use
weak-pointer-in-cpp

Problem: Circular Dependency with shared_ptr

If two objects hold shared_ptr to each other:

  • Reference count never reaches zero
  • Memory leak occurs
weak_pointer

This is the reason we use weak pointers(weak_ptr) as they are not reference counted. So, the class in which weak_ptr is declared doesn’t have a stronghold over it i.e. the ownership isn’t shared, but they can have access to these objects.

a_ptr_shared_ptr_

So, in the case of shared_ptr because of cyclic dependency use_count never reaches zero which is prevented by using weak_ptr, which removes this problem by declaring A_ptr as weak_ptr, thus class A does not own it, only has access to it and we also need to check the validity of object as it may go out of scope. In general, it is a design issue.

C++
#include <iostream>
#include <memory>
using namespace std;

class Rectangle {
    int length, breadth;

public:
    Rectangle(int l, int b) : length(l), breadth(b) {}
    int area() { return length * breadth; }
};

int main() {
    shared_ptr<Rectangle> P1(new Rectangle(10, 5));
    weak_ptr<Rectangle> P2(P1);

    cout << P1->area() << endl;
    cout << P2.use_count();
    return 0;
}

Output
50
1

Problems with Normal Pointers

  • Memory Leaks: This occurs when memory is repeatedly allocated by a program but never freed. This leads to excessive memory consumption and eventually leads to a system crash. 
  • Wild Pointers: A pointer that never be initialize with valid object or address called wild pointer.
  • Dangling Pointers: Assume there is a pointer that refers to memory which was deallocated earlier in the program, that pointer is called a dangling pointer.

Pointers vs Smart Pointers

Pointer

Smart Pointer

A pointer is a variable that maintains a memory address as well as data type information about that memory location. A pointer is a variable that points to something in memory.Smart pointers, in simple words, are classes that wrap a pointer, or scoped pointers.
It is not destroyed in any form when it goes out of its scopeIt destroys itself when it goes out of its scope
Pointers are not so efficient as they don't support any other feature. Smart pointers are more efficient as they have an additional feature of memory management. 
They are very labor-centric/manual.They are automatic/pre-programmed in nature.
Comment