Polymorphic Allocators from C++17, std:vector Growth and Hacking

code logo - Polymorphic Allocators from C++17, std:vector Growth and Hacking

The concept of a polymorphic allocator from C++17 is an enhancement to standard allocators from the Standard Library.

It’s much easier to use than a regular allocator and allows containers to have the same type while having a different allocator, or even a possibility to change allocators at runtime.

Let’s see how we can use it and hack to see the growth of std::vector containers.

In short, a polymorphic allocator conforms to the rules of an allocator from the Standard Library. Still, at its core, it uses a memory resource object to perform memory management.

Polymorphic Allocator contains a pointer to a memory resource class, and that’s why it can use a virtual method dispatch. You can change the memory resource at runtime while keeping the type of the allocator. This is the opposite to regular allocators which make two containers using a different allocator also a different type.

All the types for polymorphic allocators live in a separate namespace std::pmr (PMR stands for Polymorphic Memory Resource), in the header.

The Series

This article is part of my series about C++17 Library Utilities. Here’s the list of the articles:

cpp17indetail - Polymorphic Allocators from C++17, std:vector Growth and Hacking

Resources about C++17 STL:

OK, let’s go back to our main topic: PMR.

Core elements of pmr:

Here’s a little summary of the main parts of pmr:

  • std::pmr::memory_resource – is an abstract base class for all other implementations. It defines the following pure virtual methods:
    • virtual void* do_allocate(std::size_t bytes, std::size_t alignment),
    • virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment)
    • virtual bool do_is_equal(const std::pmr::memory_resource& other) const noexcept.
  • std::pmr::polymorphic_allocator – is an implementation of a standard allocator that uses memory_resource object to perform memory allocations and deallocations.
  • global memory resources accessed by new_delete_resource() and null_memory_resource()
  • a set of predefined memory pool resource classes:
    • synchronized_pool_resource
    • unsynchronized_pool_resource
    • monotonic_buffer_resource
  • template specialisations of the standard containers with polymorphic allocator, for example std::pmr::vector, std::pmr::string, std::pmr::map and others. Each specialisation is defined in the same header file as the corresponding container.
  • It’s also worth mentioning that pool resources (including monotonic_buffer_resource) can be chained. If there’s no available memory in a pool, the allocator will allocate from the “upstream” resource.

And we have the following predefined memory resources:

new_delete_resource()

It’s a free function that returns a pointer to a global “default” memory resource. It manages memory with the global new and delete.

null_memory_resource()

It’s a free function that returns a pointer to a global “null” memory resource which throws std::bad_alloc on every allocation. While it sounds not useful, it might be handy when you want to guarantee that your objects don’t allocate any memory on the heap. Or for testing.

synchronized_pool_resource

This is a thread-safe allocator that manages pools of different sizes. Each pool is a set of chunks that are divided into blocks of uniform size.

unsynchronized_pool_resource

A non-thread-safe pool_resource.

monotonic_buffer_resource

This is a non-thread-safe, fast, special-purpose resource that gets memory from a preallocated buffer, but doesn’t release it with deallocation. It can only grow.

An Example

Below you can find a simple example of monotonic_buffer_resource and pmr::vector:

#include 
#include    
#include             

int main() {
    char buffer[64] = {}; 
    std::fill_n(std::begin(buffer), std::size(buffer) - 1, '_');
    std::cout 'n

We Know You Better!
Subscribe To Our Newsletter
Be the first to get latest updates and
exclusive content straight to your email inbox.
Yes, I want to receive updates
No Thanks!
close-link

Subscribe to our newsletter

Sign-up to get the latest marketing tips straight to your inbox.
SUBSCRIBE!
Give it a try, you can unsubscribe anytime.