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:
-
std::unique_ptr
-
std::shared_ptr
-
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:
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:
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):
This ensures:
-
Exception safety
-
No memory leaks
-
Deterministic cleanup