This is my learning notes from the course - Mastering C++ Standard Library Features.
What Problem Do Smart Pointers Solve?
- problems with manual dynamic memory allocation
- why new/delete are considered harmful
Problems with Manual Dynamic Memory Allocation
Before C++11, dynamic memory management in C++ has been traditionally done through the use of the new
and delete
keywords.
The example below shows that the new
keyword allocates memory for a foo
instance, constructs it, and returns a pointer to the newly-allocated memory location.
The delete
keyword destroys the instance of foo
allocated at the address f
, then reclaims the dynamically allocated memory for future reuse. In addition, delete
keyword also calls the destructor if the class instance you’ve created on the heap, which might be very important if the destructor has some critical side effects.
1 |
|
There are some major problems with the use of new
/delete
:
- They are error prone. Forgetting to use the
delete
keyword or using it multiple times can lead to *”memory leaks”* or *”double-free”* errors, which can harm stability or introduce security problems. - Accessing a pointer after
delete
has been called is another common very dangerous mistake.
1 | int memory_leak() |
Problems with Using Pointers
Pointers increase cognitive overhead on development and people reading/reviewing the code. As soon as a pointer is spotted in a code base, many questions have to be asked: “was it allocated dynamically?“ “Am I suppose to delete
the pointer after using it?“, “Who is the owner of the allocated memory?“ … and so on.
Here’s the example showing that by introducing a pointer in the interface of your function, you are forced to document in a very very exhaustive manner all the actions that are executed on x
; otherwise, the caller will need to make a lot of assumptions on the use of that pointer.
1 | void bar(int* x) |
– All the issues are solved by smart pointers
.
Summary
- Manual memory management is error-prone and can lead it potentially security-critical bugs
- Manual memory management makes code harder to reason about and to read
- Smart pointers solve the aforementioned issues