Modern C++11 Memory Management
Memory management in low level code has changed slowly over the years. In
traditional C code, you would allocate memory with malloc()
and release it
with free()
.
Some of the problems with this approach were:
malloc()
might fail if the system is running low on memory, so you would have to check for aNULL
return and handle the error appropriately.- you might forget to call
free()
, thus leaking memory. This is especially common when there are multiple code paths, early returns and so on. - the memory might be referred to after its release, causing subtle bugs or crashes.
- sharing the memory between threads was error-prone and relied on complex systems to avoid leaking or trashing memory.
The above code is also perfectly valid C++, albeit not exactly idiomatic.
Rather than rely on the C runtime, C++ introduced heap management into the
language itself, with the new
and delete
operators:
This too is not without its issues:
- If the system is low on memory,
new
could fail and throw an exception (the default behaviour). This would require atry/catch
block to handle the failure, otherwise the program would abort. new
could also be configured to returnNULL
, requiring an entirely different error handling strategy.- It is generally inadvisable to mix memory allocated with
new
with memory allocated usingmalloc()
(as they could potentially be allocated in different heap areanas, and cause corruption).
Modern Memory Management
To drastically simplify memory management and reduce the potential for bugs, C++11 introduces several types of smart pointers:
std::unique_ptr
: a pointer which is automatically freed when the pointer goes out of scope, and has a single owner at all timesstd::shared_ptr
: a reference-counting pointer which can be shared among multiple threads, and deletes the object when the last reference is releasedstd::weak_ptr
: a handle which does not hold a reference, but can be materialised into astd::shared_ptr
on demand
These three smart pointer types should be able to cover the vast majority of memory management needs in a typcail application. (There will always be exceptions which need custom allocation strategies, such as high performance games, numerical processing, etc).
By using the correct smart pointer according to the desired semantics, you can virtually eliminate leaks and other common memory problems.
These are each covered in detail in their own articles below:
- Unique Pointer
- Shared Pointer
- Weak Pointer (TBA)