Allocating Memory
In C++ we can allocate memory using new
and then explicitly free
it up with delete
. But this can be dangerous—a very frequent
bug is forgetting to free up memory that you manually allocated.
Instead, we’d like to be able to have the memory freed automatically for us when the object managing it goes out of scope. This is where a unique pointer comes into play.
std::unique_ptr
is a smart pointer that manages another object and cleans up
after it when the unique_ptr
goes out of scope.
In particular, make_unique
is used to create an object and wrap it in std::unique_ptr
.
Here’s how we can allocate memory for an array of doubles and wrap it in a unique_ptr
(we also compare to the old C++ way here):
#include <iostream>
#include <memory>
int main() {
const int size(10);
// new way to allocate
auto data = std::make_unique<double []>(size);
for (int i = 0; i < size; ++i) {
data[i] = 1.0;
}
// old C++ way
double* data_old = new double [size];
for (int i = 0; i < size; ++i) {
data_old[i] = 1.0;
}
delete[] data_old;
}
Why would we want to do this?
Compared to std::array
, this allows us to specify the size at
runtime, instead of compile time. Compared to std::vector
, there
is no additional overhead to allow the array to grow, since its size
is fixed once it is created.
try it…
Test this example with valgrind to see if any memory is not freed.
Remove the delete
and try again. Notice that the
unique_ptr
version was freed when it went out of scope.