Tutorial on Smart Pointers in C++
Smart pointers in C++ provide automatic and safe memory management. They help avoid memory leaks and dangling pointers by ensuring proper object destruction through RAII (Resource Acquisition Is Initialization).
This tutorial covers the three primary smart pointers in C++:
std::unique_ptrstd::shared_ptrstd::weak_ptr
1. std::unique_ptr
unique_ptr has exclusive ownership. Only one unique pointer can own a resource at a time.
Example: Owning a Simple Object
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> p = std::make_unique<int>(42);
std::cout << "Value: " << *p << "\n";
// Transfer ownership
std::unique_ptr<int> q = std::move(p);
if (!p) std::cout << "p is now null\n";
std::cout << "q points to: " << *q << "\n";
}
Example: Building a Linked List
struct Node {
int val;
std::unique_ptr<Node> next;
Node(int v) : val(v), next(nullptr) {}
};
void printList(const std::unique_ptr<Node>& head) {
const Node* curr = head.get();
while (curr) {
std::cout << curr->val << " ";
curr = curr->next.get();
}
std::cout << "\n";
}
int main() {
auto head = std::make_unique<Node>(1);
head->next = std::make_unique<Node>(2);
head->next->next = std::make_unique<Node>(3);
printList(head);
}
2. std::shared_ptr
shared_ptr allows multiple owners of a resource. It maintains a reference count and deletes the object when the last reference is gone.
Example: Shared Ownership
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> a = std::make_shared<int>(100);
std::shared_ptr<int> b = a;
std::cout << "a use count: " << a.use_count() << "\n";
std::cout << "b use count: " << b.use_count() << "\n";
std::cout << "*b = " << *b << "\n";
}
Example: Shared Linked List
struct Node {
int val;
std::shared_ptr<Node> next;
Node(int v) : val(v), next(nullptr) {}
};
3. std::weak_ptr
weak_ptr is a non-owning reference to an object managed by shared_ptr. It is used to prevent circular references that lead to memory leaks.
Example: Breaking a Circular Reference
#include <iostream>
#include <memory>
struct B;
struct A {
std::shared_ptr<B> b_ptr;
~A() { std::cout << "A destroyed\n"; }
};
struct B {
std::weak_ptr<A> a_ptr;
~B() { std::cout << "B destroyed\n"; }
};
int main() {
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->b_ptr = b;
b->a_ptr = a;
}
Is There a make_weak?
No, there is no std::make_weak. This is because weak_ptr does not own memory and must point to an existing shared_ptr.
How to Create a weak_ptr
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> sp = std::make_shared<int>(42);
std::weak_ptr<int> wp = sp;
if (auto locked = wp.lock()) {
std::cout << "Value: " << *locked << "\n";
} else {
std::cout << "Object no longer exists\n";
}
}
Summary
| Smart Pointer | Ownership | Thread Safe Ref Counting | Use Case |
|---|---|---|---|
unique_ptr |
Exclusive | N/A | Fast, safe, sole ownership |
shared_ptr |
Shared | Yes | Shared ownership |
weak_ptr |
None | N/A | Break circular refs in shared_ptr |
C/C++ Programming
- Understanding std::transform_reduce in Modern C++
- Implement a Lock Acquire and Release in C++
- Detecting Compile-time vs Runtime in C++: if consteval vs std::is_constant_evaluated()
- C++ Forward References: The Key to Perfect Forwarding
- Understanding dynamic_cast in C++: Safe Downcasting Explained
- C vs C++: Understanding the restrict Keyword and its Role in Optimization
- C++ Lvalue, Rvalue and Rvalue References
- C++ assert vs static_assert
- Why auto_ptr is Deprecated in C++?
- C++ What is the consteval? How is it different to const and constexpr?
- Tutorial on C++ std::move (Transfer Ownership)
- const vs constexpr in C++
- Tutorial on C++ Ranges
- Tutorial on C++ Smart Pointers
- Tutorial on C++ Future, Async and Promise
- The Memory Manager in C/C++: Heap vs Stack
- The String Memory Comparision Function memcmp() in C/C++
- Modern C++ Language Features
- Comparisions of push_back() and emplace_back() in C++ std::vector
- C++ Coding Reference: is_sorted_until() and is_sorted()
- C++ Coding Reference: iota() Setting Incrementing Values to Arrays or Vectors
- C++ Coding Reference: next_permutation() and prev_permutation()
- C++ Coding Reference: count() and count_if()
- C++ Code Reference: std::accumulate() and Examples
- C++ Coding Reference: sort() and stable_sort()
- The Next Permutation Algorithm in C++ std::next_permutation()
–EOF (The Ultimate Computing & Technology Blog) —
831 wordsLast Post: From Idea to GitHub Pages: Building Tools with AI and Vibe Coding
Next Post: Tutorial on C++ Ranges