Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is std::allocator a template?

Tags:

c++

The job of an allocator is to obtain "raw" memory via its allocate method. What the caller constructs in the memory returned by the allocator is of no concern to the allocator (right?). So why is std::allocator a template when this only seems to add unnecessary complexity? What does the allocator actually do with that type information? Why does it have to know the type of object the memory is for? I'm assuming that there is some obvious reason that I'm missing, so what is that reason?

like image 668
antred Avatar asked Jul 23 '17 16:07

antred


People also ask

What is a std :: allocator?

std::allocator is the default memory allocator for the standard library containers, and you can substitute your own allocators. This allows you to control how the standard containers allocate memory.

What is allocator type in C++?

Allocators are used by the C++ Standard Library to handle the allocation and deallocation of elements stored in containers. All C++ Standard Library containers except std::array have a template parameter of type allocator<Type> , where Type represents the type of the container element.

What is the use of allocator?

Allocators are objects responsible for encapsulating memory management. std::allocator is used when you want to separate allocation and do construction in two steps. It is also used when separate destruction and deallocation is done in two steps.

What is a pool allocator?

A Pool allocator (or simply, a Memory pool) is a variation of the fast Bump-allocator, which in general allows O(1) allocation, when a free block is found right away, without searching a free-list. To achieve this fast allocation, usually a pool allocator uses blocks of a predefined size.


2 Answers

Well, std::allocator, and the Allocator concept itself, were invented to deal with issues like near- and far-pointers, or generally pointers to different address-spaces. And they deal with that ... adequately. The allocator determines the pointer-type used.

They can also be used to deal with different memory-allocators, though the amount of boilerplate for that is somewhat staggering.

And finally, an allocator-aware container can coupled with an allocator taking advantage of that provide a sub-allocator to child-elements, which might help reduce overhead.


The first point is nowadays mostly obsolete, though it can be used with the second point to have a mapping-address-invariant container in a shared memory segment, or a file.

The second point can be used for taking advantage of specialized allocators, though the interface is not really good for that. An example where I used it to hack me a secure std::basic_string.

And the last point is rarely used.


The one huge disadvantage of the Allocator concept as defined is the fact that it uses a template. All use already goes through std::allocator_traits<Allocator>, so it just leads to types inadvertently being almost the same, were there not the template-argument to the allocator.
And also to much duplicated code to rebind the allocator appropriately.

like image 165
Deduplicator Avatar answered Sep 24 '22 14:09

Deduplicator


Alignment comes to mind. Different types have different alignment requirements, a memory location that is good for a char array may not be good for a double (which generally require 8-byte aligned addresses).

OTOH, it should be noted that malloc solves this problem by providing memory that have a correct alignment for the most stringent of the built-in types, which is generally a good enough solution for a general-purpose allocator.

like image 36
Matteo Italia Avatar answered Sep 21 '22 14:09

Matteo Italia