This post starts a miniseries about an almost unknown feature in C++17: polymorphic allocators. I often promised that I would write about polymorphic allocators. Today, I fulfill my promise.
Since C++98, you can fine-tune memory allocation in general but also for user-defined types or containers of the standard library. For example, the containers of the sequential and associative containers of the STL have a defaulted allocator parameter. For example, here are the containers
The memory is allocated from the heap by default, but this default is not always appropriate. Often, you want to apply another strategy. Here are a few ideas.
- You want to use the stack instead of the heap for memory allocation.
- You want to use your memory allocation strategy and reduce the number of memory allocations.
- You want to allocate contiguous memory blocks to benefit from CPU caching.
- You want to allocate but don’t deallocate memory.
- You want to reuse a memory pool.
- You want to have a thread-safe memory allocation.
- You want to use different allocators for different types.
- You want to change the allocation strategy for a type if its size increases.
With C++98, you could implement and use your memory allocator, but this was pretty challenging and error-prone. I have already written two posts about memory allocators in C++: “Memory Management with
std::allocator” and a guest post from Jonathan Müller “Memory Pool Allocators“.
Thanks to polymorphic allocators in C++17, your job becomes way easier. Before I dive into the details, let me give you an introductory example.
First, I allocate memory on the stack. I can use a
byte array (line 1) or a char array (line 2) for that job. Furthermore, I initialize a
std:pmr::motonotic_buffer with the address and the size of the already stack-allocated memory. The final step is that the
std::pmr::vector takes this memory resource.
The namespace component pmr stands for a polymorphic memory resource. All components of the polymorphic allocators are in this namespace. The containers of the STL have their pmr pendants. This pmr pendant is an alias for a
std::vector using the special allocator. The following two lines are equivalent:
When you study the example
polymorphicAllocator.cpp, you may wonder: How could a vector of 200
int‘s myVec2 fit into a
char array of 200 elements? The answer is simple:
std::pmr::new_delete_resource() as the so-called upstream allocator kicks in as a
Predefined Memory Resources
I will apply the listed predefined memory resources in upcoming posts. Therefore, here is a short overview. All predefined memory resources are derived from the interface class
std::pmr::memory_resource. The class provides three public member functions
std:pmr::memory_resource has three private virtual member functions
do_is_equal. Typically, a user-defined memory resource overwrites these three virtual member functions, as do the predefined memory resources:
Returns a pointer to a memory resource, calling the global
delete. It is the default memory resource if not otherwise specified.
Returns a pointer to a “null” memory resource. Using this memory resource for allocating causes a
std::bad_alloc exception. This memory resource ensures you do not arbitrarily allocate memory on the heap.
A class that creates a memory resource with less fragmentation that is thread-safe. This class acts as a wrapper around the default resource.
A class that creates a memory resource with less fragmentation that is not thread-safe. This class acts as a wrapper around the default resource.
A class to create memory resources in a big chunk of memory that is not thread-safe. You can optionally pass it as a buffer. This memory resource is pretty fast and can only grow. It destroys the objects but does not free the memory.
I used in the previous program
std::pmr::monotonic_buffer with a
byte-array (line 1) and a
char-array (line 2) as a passed buffer. Additionally, the vector
myVec2 allocated the remaining memory with the default allocator (upstream allocator)
Admittedly, his was a technical post. In my next post, I will apply the theory and implement a tracking memory resource. This user-defined memory resource will track all allocations and deallocations of the upstream allocator.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, Marco Parri Empoli, moon, and Philipp Lenk.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
|My special thanks to SHAVEDYAKS|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,