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)
#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.

#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.

#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.

#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

Problem: Circular Dependency with shared_ptr
If two objects hold shared_ptr to each other:
- Reference count never reaches zero
- Memory leak occurs

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.

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.
#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 scope | It 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. |