If you’re writing code that’s doing lots of memory allocations (e.g. lots of nodes being created in some huge graph at runtime and/or you’re also doing lots of type erasure, and most importantly you can’t know in advance how many you’ll need) then you might wanna take a look at C++17’s std::pmr
instead of trying to write your own allocators (which is still a good idea if the goal is just to learn).
In particular, what would interest you the most are the memory resources themselves, which are in the memory_resource
header file (https://en.cppreference.com/w/cpp/header/memory_resource ).
I had great success using in particular unsynchronized_pool_resource
(perfect in single-threaded settings where you’re sure you don’t want other threads to access that resource) and monotonic_buffer_resource
(perfect when you don’t care about reusing previously freed memory and care more about speed, so that the cost of one allocation is then just a pointer increment inside a buffer and “deallocation” is a no-op) in our production code and, depending on the scenario, achieved speedups between x2 and x3 compared to using the standard allocator.
You can directly use the .allocate
and .deallocate
member functions of those resources (although the semantics will be a bit different from your usual malloc
and free
, as you need to remember the alignment and the size of the allocated space when you want to deallocate). You also have standard containers inside std::pmr
that can be bound to one of those memory resources in a type-erased way (hence the “polymorphic” in the name), like std::pmr::vector
or std::pmr::list
.
There’s also an awesome CppCon talk by John Lakos in two parts which explains those allocation strategies: