Smart pointerek
Smart Pointers¶
One major disadvantage of using pointers is that memory deallocation must be handled by the developer, and failing to free even a single allocation can cause significant problems. Using smart pointers reduces this responsibility, as memory allocation and deallocation happen automatically.
Smart pointers are so-called template classes. This means that when using them, we must specify the type they will manage between the '<' and '>' characters. To use smart pointers, the memory header must be included.
When working with raw pointers, the following operations are the most important: - memory allocation - copying - memory deallocation
With smart pointers, we wrap the pointer itself inside a wrapper class, and by instantiating the wrapper class, we create the pointer. Therefore, these objects should not be considered as dynamically allocating types themselves (like the Course class where we stored Students), but as direct replacements for raw pointer types. These classes implement the * and -> operators, so we can use them with regular pointer syntax.
Memory allocation¶
When the smart pointer object is instantiated, it is possible to allocate memory.
(A smart pointer can allocate memory in other ways as well, but here we focus only on allocation through the constructor.)
After allocation, the smart pointer continuously manages the memory.
Memory deallocation¶
Smart pointer objects also have a lifetime, just like any regular object. When an object ceases to exist, it can no longer be referenced. For a raw pointer, this means we must free the allocated memory before the pointer goes out of scope; otherwise, with no remaining references, we won’t know which memory region should be freed.
When a smart pointer object is destroyed, its destructor runs, and the smart pointer automatically frees the allocated memory.
Copying¶
In the dynamic memory chapter, copying caused most of the difficulties, as we wanted to achieve deep-copy.
When copying a pointer, memory is not allocated by default, since only values are being assigned.
(This is why it is important to emphasize that this is not an object that uses dynamic memory internally, but rather a pointer replacement.)
The copying behavior can be defined using the assignment operator and the copy constructor.
Unique Pointer¶
Often, we need a memory region to be accessible through only one variable. In such cases, we can use the std::unique_ptr type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
As seen in the example above, copying is not allowed with a unique pointer. This guarantees that a single memory address cannot belong to two objects (variables). However, copying can still be required in certain situations — for example, when setting up temporary memory — so this must be handled as well.
In this case, our task was to free the originally allocated memory and update the memory address. What we did not have to worry about was preventing the copied-from element from accessing the memory afterward.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Shared pointer¶
In the case of a shared pointer, we expect that the same memory address can be referenced by multiple objects (variables). The task to be solved here is ensuring that the memory is freed only when no object (variable) references that memory address anymore. With a shared pointer, this is handled automatically, so we do not need to take care of it ourselves.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Created: 2025-11-27