Introduction to Smart Pointers and Why
1
12:10-13:10, Tue, 6th September 2022
60 minutes | Introductory Audience
Social: @MichaelShah�Web: mshah.io�Courses: courses.mshah.io
YouTube: www.youtube.com/c/MikeShah
Introduction to Smart Pointers and Why
2
12:10-13:10, Tue, 6th September 2022
60 minutes | Introductory Audience
Social: @MichaelShah�Web: mshah.io�Courses: courses.mshah.io
YouTube: www.youtube.com/c/MikeShah
Some emphasis on this being an introduction today
Introduction to Smart Pointers and Why
3
12:10-13:10, Tue, 6th September 2022
60 minutes | Introductory Audience
Social: @MichaelShah�Web: mshah.io�Courses: courses.mshah.io
YouTube: www.youtube.com/c/MikeShah
The ‘why’ turned this into a ‘systems look’ regarding memory that should be useful for your foundational knowledge
Please do not redistribute slides without prior permission.
4
Goal(s) for today
5
What you’re going to learn
6
Your Tour Guide for Today�by Mike Shah (he/him)
7
Code for the talk
8
Abstract
Pointers are one of the most powerful tools in the C++ language available to programmers. Pointers allow sharing of resources, and for programmers to take control of the lifetime of their objects. However-- 'with great power comes great responsibility'. In this talk I am going to begin with how programmers can 'wrap' a raw pointer in a class to create a smart pointer that takes advantage of RAII to reclaim resources. I will then introduce in the standard library each of unique_ptr, shared_ptr, and weak_ptr. Beginners who have never seen these before will leave with concrete advice on where to use each of the following and for what scenarios where they previously had used raw pointers. Finally, at the end of the talk, I will give a brief insight into Smart pointer adaptors in C++23 (out_ptr_t, out_ptr, inout_ptr_t, and inout_ptr).
9
The abstract that you read and enticed you to join me is here!
Prerequisite Knowledge for this Presentation
10
What is a raw pointer?
11
42
0xf8888888
0xf8888888
0xf8888884
int x = 42;�
(int)
int* px = &x;
�(pointer to integer)
Prerequisite Refresher
12
Let’s start with memory
(And there are many kinds of memory)
13
We have many types of physical memory
14
Memory Hierarchy (1/2)
15
Memory Hierarchy (2/2)
16
Programmers View of working (or ‘main’) memory (1/3)
17
Address (in Hex) | Value |
0x1000000B | |
0x1000000A | |
0x10000009 | |
0x10000008 | |
0x10000007 | |
0x10000006 | |
0x10000005 | |
0x10000004 | |
0x10000003 | |
0x10000002 | |
0x10000001 | |
0x10000000 | |
Programmers View of working (or ‘main’) memory (2/3)
18
Address (in Hex) | Value |
0x1000000B | |
0x1000000A | |
0x10000009 | |
0x10000008 | |
0x10000007 | |
0x10000006 | |
0x10000005 | |
0x10000004 | |
0x10000003 | |
0x10000002 | |
0x10000001 | |
0x10000000 | |
Programmers View of working (or ‘main’) memory (3/3)
19
Address (in Hex) | Value |
0x1000000B | |
0x1000000A | |
0x10000009 | |
0x10000008 | |
0x10000007 | |
0x10000006 | |
0x10000005 | |
0x10000004 | |
0x10000003 | |
0x10000002 | |
0x10000001 | |
0x10000000 | |
42
Operating System View of Processes (1/3)
20
20
Address (in Hex) | Value |
0x10000000 �+ N bytes | |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Operating System View of Processes (2/3)
21
Address (in Hex) | Value |
0x20000000 + M | |
... | |
... | |
0x20000000 | |
... | |
... | |
... | |
... | |
0x10000000 + N | |
... | |
... | |
0x10000000 | |
Process B
Process A
Operating System View of Processes (3/3)
22
Address (in Hex) | Value |
0x20000000 + M | |
... | |
... | |
0x20000000 | |
... | |
... | |
... | |
... | |
0x10000000 + N | |
... | |
... | |
0x10000000 | |
Process B
Process A
A Single Processes Memory Segments (1/3)
23
Address (in Hex) | Value |
0x10000000 + N | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Process A
A Single Processes Memory Segments (2/3)
24
Address (in Hex) | Value |
0x10000000 + N | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
A Single Processes Memory Segments (3/3)
25
Address (in Hex) | Value |
0x10000000 + N | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Let’s start with the stack
A Process and its stack memory (1/5)
26
Address (in Hex) | Value |
0x16d5ff988 | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
A Process and its stack memory (2/5)
27
Address (in Hex) | Value |
0x16d5ff988 | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
A Process and its stack memory (3/5)
28
Address (in Hex) | Value |
0x16d5ff988 | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
42
A Process and its stack memory (4/5)
29
Address (in Hex) | Value |
0x16d5ff988 | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
42
A Process and its stack memory (5/5)
30
Address (in Hex) | Value |
0x16d5ff988 | |
... | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
42
Stack Allocation With Multiple Variables (1/4)
31
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Stack Allocation With Multiple Variables (2/4)
32
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
(x) 42
Stack Allocation With Multiple Variables (3/4)
33
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
(x) 42
(y) 42
Stack Allocation With Multiple Variables (4/4)
34
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
(x) 42
(y) 42
Automatic Memory Management -- Local Variables Popped off stack (1/5)
35
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
(x) 42
(y) 42
Automatic Memory Management -- Local Variables Popped off stack (2/5)
36
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
(x) 42
(y) 42
Stack Pointer
Automatic Memory Management -- Local Variables Popped off stack (3/5)
37
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
(x) 42
???
Stack Pointer
Automatic Memory Management -- Local Variables Popped off stack (4/5)
38
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
???
???
Stack Pointer
Automatic Memory Management -- Local Variables Popped off stack (5/5)
39
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
???
???
Stack Pointer
So at this point:
Audience Poll: How much data do you see here?
a.) A lot
b.) Very little
40
Nanite | Inside Unreal�https://youtu.be/TMorJX3Nj6U?t=5255
Audience Poll: How much data do you see here?
a.) A lot
b.) Very little
41
Nanite | Inside Unreal�https://youtu.be/TMorJX3Nj6U?t=5255
Humor me here -- there’s ‘a lot’ of data (and that is probably an understatement!)
Can we store all this data on the stack? (1/2)
42
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Stack Pointer
Can we store all this data on the stack? (2/2)
43
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Stack Pointer
Heap Memory
For Dynamic Memory Allocations
44
44
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Heap Memory
45
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Heap Visualization (1/8)
46
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
0x70000000
0x70000000 + N
Heap Visualization (2/8)
47
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
4
0x70000000
0x70000000 + N
Heap Visualization (3/8)
48
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
77
4
0x70000000
0x70000000 + N
Heap Visualization (4/8)
49
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
77
4
0x70000000
0x70000000 + N
(Aside)
Heap Visualization (5/8)
50
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
77
4
0x70000000
0x70000000 + N
Heap Visualization (6/8)
51
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
77
4
0x70000000
0x70000000 + N
Heap Visualization (7/8)
52
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
77
4
0x70000000
0x70000000 + N
Heap Visualization (8/8)
53
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
????????
?
0x70000000
0x70000000 + N
Let’s take a quick breather and recap
54
Recap of Stack and Heap (1/2)
55
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Recap of Stack and Heap (2/2)
56
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Let’s take a closer look at heap allocations.
Heap allocated memory means we have the added responsibility of manually managing these objects lifetime.
Heap Allocations
57
Heap Allocation Responsibility (1/5)
58
Heap Memory
Heap Allocation Responsibility (2/5)
59
First integer allocation in our loop
4
Heap Memory
Heap Allocation Responsibility (3/5)
60
First integer allocation in our loop
4
Heap Memory
Second allocation in our loop
4
Heap Allocation Responsibility (4/5)
61
First integer allocation in our loop
4
Heap Memory
....
4
Nth integer allocation in our loop
4
Heap Allocation Responsibility (5/5)
62
First integer allocation in our loop
4
Heap Memory
....
4
Nth integer allocation in our loop
4
Leak Visual (1/9)
63
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
Leak Visual (2/9)
64
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
Leak Visual (3/9)
65
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
allocateResource = 0;
Leak Visual (4/9)
66
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
allocateResource = 0;
Leak Visual (5/9)
67
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
allocateResource = 0xff123456;
First integer allocation in our loop
4
Leak Visual (6/9)
68
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
?????
First integer allocation in our loop
4
Leak Visual (7/9)
69
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
?????
First integer allocation in our loop
4
Leak Visual (8/9)
70
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
Every time, I run this code, I allocate on the stack ‘allocateResource’.
The memory ‘allocateResource’ points to is on the heap.
But when I exit scope (in this case restart the loop), I lose that pointer on the stack!
First integer allocation in our loop
4
allocateResource = 0xFF122432;
Second allocation in our loop
4
Leak Visual (9/9)
71
Heap Memory
Address (in Hex) | Value |
0x16d7f38d8 | |
0x16d7f38d4 | |
... | |
| |
... | |
... | |
... | |
... | |
... | |
... | |
... | |
0x10000000 | |
Stack
Code
Data
Heap
And we have no pointer now to this first allocation.
This is the ‘leak’ as this resource will remain for our programs duration
First integer allocation in our loop
4
allocateResource = 0xFF122432;
Second allocation in our loop
4
Memory Leak Fix
72
One fix is to ‘delete allocateResource’ within the scope.
Memory Leak Fix - Slight code update (1/2)
73
Memory Leak Fix - Slight code update (2/2)
74
This time we use ‘delete[] allocateResource’
(The left side has a memory leak, the right side is correct now)
Not always so obvious though on where to delete
75
Reminder on Object Destruction RAII
76
Building a Smarter Pointer
(By wrapping a raw pointer)
77
Wrap Raw Pointer allocating on the heap and utilize RAII
78
Safety with RAII -- called destructor
79
Constructing a Smarter Pointer - template
80
Constructing a Smarter Pointer - delete/delete[]
81
Constructing a Smarter Pointer - operator=
82
A Smart Pointer that shares data (1/11)
83
A Smart Pointer that shares data (2/11)
84
84
Heap Memory
s data
s
A Smart Pointer that shares data (3/11)
85
85
Heap Memory
s data
s
s1 data
s1
A Smart Pointer that shares data (4/11)
86
86
Heap Memory
s data
s
s1 data
s1
s2 data
s2
A Smart Pointer that shares data (5/11)
87
Heap Memory
s data
s
s1 data
s1
s2 data
s2
A Smart Pointer that shares data (6/11)
88
Heap Memory
s2 data (s data deleted)
s
s1 data
s1
s2 data
s2
A Smart Pointer that shares data (7/11)
89
Heap Memory
s2 data (s data deleted)
s
s1 data
s1
s2 data
s2
A Smart Pointer that shares data (8/11)
90
Heap Memory
s2 data (s data deleted)
s
s2 data (s1 data deleted)
s1
s2 data
s2
A Smart Pointer that shares data (9/11)
91
Heap Memory
s2 data (s data deleted)
s
s2 data (s1 data deleted)
s1
s2 data
s2
A Smart Pointer that shares data (10/11)
92
Heap Memory
s2 data (s data deleted)
s
s2 data (s1 data deleted)
s1
s2 data
s2
A Smart Pointer that shares data (11/11)
93
Heap Memory
s2 data (s data deleted)
s
s2 data (s1 data deleted)
s1
s2 data
s2
As soon as one of the destructors is called, recall each SmartPtr points to the same piece of now deleted memory. This gives us a double free error.
Recap
94
Smart Pointer Design Decisions on ownership
95
Understanding Ownership
96
Understanding Ownership -- Unique Owner (1/2)
97
Understanding Ownership -- Unique Owner (2/2)
98
Understanding Ownership -- More than one owner? (1/2)
99
Understanding Ownership -- More than one owner? (2/2)
100
Design of Smart Pointers that can share
101
SmartPtr<int> s
SmartPtr<int> s1
SmartPtr<int> s2
Control Block “The s’s”
atomic<int> references = 3
Core cpp 2022
102
Using our Smart Pointer (1/2)
103
Using our Smart Pointer (2/2)
104
C++ 11 Smart Pointers in STL
#include <memory>
105
#include <memory> for Three STL Smart Pointers
106
What problem does a smart pointer solve?
107
std::unique_ptr
108
std::shared_ptr
109
std::weak_ptr
110
Another std::weak_ptr
111
std::auto_ptr - deprecated
112
Conclusion
Wrapping up what we’ve learned
113
Conclusion -- C++ Programmers
114
Further resources and training materials
115
For educators and trainers, the ISOCPP Guidelines
116
Bonus if Time
117
118
New in C++ 23 - out_ptr, inout_ptr
119
Introduction to Smart Pointers and Why
120
12:10-13:10, Tue, 6th September 2022
60 minutes | Introductory Audience
Social: @MichaelShah�Web: mshah.io�Courses: courses.mshah.io
YouTube: www.youtube.com/c/MikeShah
Thank you!
Thank you!
121
Extras and Notes
122
Talk Outline
123