Skip to content

Instantly share code, notes, and snippets.

@vinniefalco
Created August 31, 2020 18:49
Show Gist options
  • Save vinniefalco/96a14e591992e839e99770acc0b54750 to your computer and use it in GitHub Desktop.
Save vinniefalco/96a14e591992e839e99770acc0b54750 to your computer and use it in GitHub Desktop.
A polymorphic allocator constructs with a pointer to a memory resource:
// A type of memory resource
std::pmr::monotonic_buffer_resource mr;
// Construct a vector using the monotonic buffer resource
std::pmr::vector< T > v1( std::pmr::polymorphic_allocator< T >(&mr) );
// Or this way, since construction from memory_resource* is implicit:
std::pmr::vector< T > v2( &mr );
The code above illustrates a design defect in the standard's polymorphic
allocators. The memory resource is passed by pointer, and ownership is not
transferred. Thus the caller is responsible for its lifetime, otherwise
undefined behavior results when the vector tries to allocate or deallocate
memory from a resource that has been destroyed. Another problem with
non-owning pointers is that a library cannot return a container which
uses its own custom memory resource:
namespace my_library {
std::pmr::vector<char> get_chars()
{
// This leaks memory because `v` does not own the memory resource
std::pmr::vector<char> v( new my_resource );
}
} // my_library
Workarounds for this problem are worse than the problem itself. The library
could return a pair with the vector and `unique_ptr<memory_resource>`
which the caller must manage. Or the library could change its function
signatures to accept a `memory_resource*` provided by the caller, where
the library also makes public the desired memory resources
(`my_resource` above). These solutions are unsatisfying.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment