I've recently been trying to understand how c++ allocators work, and I've been looking to the implementation of the red-black tree that the STL library uses for things like std::set
or std::map
, but there are some things that I can't get my head around.
The first thing that does is convert the allocator from the type the container has to store - _Val
- to the type of the node that the tree uses - _Rb_tree_node<_Val>
- using the rebind template:
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
This I can sort out.
Now, when an element is inserted and it needs to create a new node what it does is this
_Node_type __node = _Alloc_traits::allocate(_M_get_Node_allocator(), 1);
which I assume allocates space for a single node. But then it does this
::new(__node) _Rb_tree_node<_Val>;
which I really don't know what it does, since the space for __node
has already been allocated. But after that it also does this
_Alloc_traits::construct(_M_get_Node_allocator(), __node->_M_valptr(), ...);
which makes me even more confused, because is supposedly constructing a node (is the node allocator), but it passes the pointer __node->_M_valptr()
which is of type _Val*
.
If someone could explain this, I would be very grateful.
operator new
does not allocate memory, it creates an object (and sometimes also allocate memory, but not in your case). So, I'd say the second line (::new(__node) _Rb_tree_node<_Val>;
) probably constructs the node in the__node
allocated memory block – Pacifistic__node
to the operator? Furthermore, if it does construct the node, what does the::construct()
do afterwards? – Firecurenew
syntax. And how else would it know where to place thenew
object? – Takenew
keyword in normal usage does two things: it allocates memory, and then it calls theoperator new
function and passes it a pointer to the memory, and this function uses the constructor to create the object at that location in memory. – Ottilie