13

How does std::list allocate the nodes in which it keeps the next/prev pointers and the T element it contains?

I think that standard allocators can only be used to allocate memory for one type (because std::allocator::allocate allocates memory in increments of sizeof(T)). So it seems impossible to allocate the list node and the contained object in a single allocation, which means that the nodes have to be allocated with whatever the implementation decides, and the nodes store pointers to the objects instead of the objects themselves, and this implies two levels of indirection to get from a pointer to a list node to the object it contains, which seems inefficient. Is this the case?

asdf
  • 153
  • 1
  • 5
  • What prevents you from having a Node structure with both pointers and a `T` as a member ? – Quentin Jul 26 '14 at 19:48
  • @Quentin because the template argument to the allocator that `std::list` uses is the same type as the list stores, not a `node` structure. This is the reason for my question. – asdf Jul 26 '14 at 19:49
  • Oh, I see now. Good question. – Quentin Jul 26 '14 at 19:53

1 Answers1

9

The allocator has a member template class, rebind, which is responsible for allocating other types. The page for std::allocator here actually has an example of the exact thing you are asking. I will quote it here:

until C++11

std::list<T, A> allocates nodes of some internal type Node<T>, using the allocator A::rebind<Node<T>>::other

since C++11

std::list<T, A> allocates nodes of some internal type Node<T>, using the allocator std::allocator_traits<A>::rebind_alloc<Node<T>>, which is implemented in terms of A::rebind<Node<T>>::other if A is an std::allocator

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • Oh wow, I should have read that page more thoroughly before I asked. Thanks. – asdf Jul 26 '14 at 20:05
  • 1
    This means that the allocator given to `list`, the one which allocates `T`s, is never used, correct? – asdf Jul 26 '14 at 20:06
  • @asdf: That's up to the implementation. But in the case of the most obvious implementation, as far as I can tell, that is correct. – Benjamin Lindley Jul 26 '14 at 20:09
  • `std::allocator` page says rebind is deprecated in c++17 and removed in c++20, so how does it work the latest versions? – e271p314 Apr 12 '20 at 19:28
  • https://stackoverflow.com/questions/38565365/why-did-stdallocator-lose-member-types-functions-in-c17 – e271p314 Apr 12 '20 at 19:36