So what is an Allocator? According to Arthur O’Dwyer “An Allocator is a handle to a heap”. I highly recommend watching his speech on 2018 C++Now, it’s more technical and in details explanation of what I cover in this article.

But before we dive any deeper into that question, a short historical overview. Alexander Stepanov (the father of STL) came up with the idea of Allocator and the motivation was to make the containers completely independent of the underlying memory model. He intended to make allocators completely encapsulate the memory model, but the standards committee found it dangerous, as this approach would lead to unacceptable efficiency degradations. As a result, the current purpose of allocators is to give the programmer control over memory allocation within containers, rather than to adopt the address model of the underlying hardware. Not what Stepanov had in mind but still helpful in some scenarios. Unfortunately, these scenarios are super rare, and the Allocator just became “that last template parameter”.

Each container instance has a single instance of Allocator in it. It’s asking the allocator for storage to store the elements. The basic functionality the allocator is expected to have is the following:

T* allocate(size_t n); allocates enough storage to store n instances of T and returns a pointer to it

allocates enough storage to store instances of and returns a pointer to it void deallocate(T* p, size_t n); releases the storage

releases the storage void construct(T* p, Args ... args); constructs an object with args parameters where p points to

constructs an object with parameters where points to void destroy(T* p); calls the destructor of the object where p points to

Actually, the best practice for containers is not to call this functions directly, and STL containers don’t do it either. Instead, they call static functions of std::allocator_traits<AllocT> . When writing your own allocator you have to make it acceptable for allocator_traits , so that it will work for STL containers. It also will take care of a huge part of requirements, easing up your job. An important thing to note is that the last two functions ( construct and destroy ) are deprecated in C++17 and will be removed in C++20, instead the allocator_traits will simply do a placement new and call destructor respectively. So, if you’ll be writing your own container, use allocator_traits interface.