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:
-
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:
-
p2owns memory -
p1becomes 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