Smart Pointers in C++
In C++, pointers are the variables that stores the memory addresses. They are extensively used in dynamic memory location to store the address of allocated memory. But they bring a lot of issues.
Problems with Normal Pointers
- Memory s: 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.
Example:
#include <iostream>
using namespace std;
int main() {
// Infinite Loop
while (1) {
// Create a variable
// in heap memory using pointer
int* ptr = new int;
}
return 0;
}
In the above example, a memory occurs because memory is allocated but not freed after use.
Smart Pointers
Smart pointer is wrapper class over a pointer that acts as a pointer but automatically manages the memory it points to. It ensures that memory is properly deallocated when no longer needed, preventing memory s. It is a part of <memory> header file.
Smart pointers are implemented as templates so we can create a smart pointer to any type of memory.
Types of Smart Pointers
C++ libraries provide implementations of smart pointers in the following types:
- auto_ptr
- unique_ptr
- shared_ptr
- weak_ptr
1. auto_ptr
In C++, auto_ptr is a smart pointer that automatically manages the lifetime of a dynamically allocated object. It takes ownership of the object it points to, ensuring that the object is automatically deleted when the auto_ptr goes out of scope.
Syntax:
auto_ptr <type> name;
where,
- type: Pointer type.
- name: Name assigned to the pointer.
Example:
#include <bits/stdc++.h>
using namespace std;
int main() {
// Pointer declaration
auto_ptr<int> ptr1(new int(10));
cout << *ptr1 << endl;
// Transfer ownership to
// pointer ptr2,
auto_ptr<int> ptr2 = ptr1;
cout << *ptr2;
return 0;
}
Output
10 10
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.

Example:
#include <bits/stdc++.h>
using namespace std;
class Rectangle {
int length;
int 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;
// Copy the addres of P1 into p2
P2 = move(P1);
cout << P2->area();
return 0;
}
Output
50 50
3. shared_ptr
By using shared_ptr, more than one pointer can point to same object at a time, and it will maintain a reference counter using the use_count() method.

Example:
#include <bits/stdc++.h>
using namespace std;
class Rectangle {
int length;
int 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));
cout << P1->area() << endl;
shared_ptr<Rectangle> P2;
// P1 and P2 are pointing
// to same object
P2 = P1;
cout << P2->area() << endl;
cout << P1->area() << endl;
cout << P1.use_count();
return 0;
}
Output
50 50 50 2
4. weak_ptr
weak_ptr is a smart pointer that holds a non-owning reference to an object. It's much more similar to shared_ptr except it will not maintain a reference counter. In this case, a pointer will not have a stronghold on the object. The reason is to avoid the circular dependency created by two or more object pointing to each other using shared_ptr.

Example:
#include <bits/stdc++.h>
using namespace std;
class Rectangle {
int length;
int breadth;
public:
Rectangle(int l, int b) {
length = l;
breadth = b;
}
int area() { return length * breadth; }
};
int main() {
// Create shared_ptr Smart Pointer
shared_ptr<Rectangle> P1(new Rectangle(10, 5));
// Created a weak_ptr smart pointer
weak_ptr<Rectangle> P2 (P1);
cout << P1->area() << endl;
// Returns the number of shared_ptr
// objects that manage the object
cout << P2.use_count();
return 0;
}
Output
50 1
If you're curious about what the differences are between all of them., refer this article - auto_ptr vs unique_ptr vs shared_ptr vs weak_ptr
Pointers vs Smart Pointers
Differences between pointers and smart pointers are mentioned below:
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. |