Я недавно пытался понять, как работают распределители C++, и я искал реализацию красно-черного дерева, которое использует библиотека STL для таких вещей, как std::set
или std::map
, но есть некоторые вещи, от которых я не могу опустить голову.Использование Allocator в C++ (STL Tree)
Первое, что делает преобразование аллокатора от типа контейнера должен хранить - _Val
- к типу узла, который использует дерево - _Rb_tree_node<_Val>
- с помощью шаблона переназначения:
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;
Этих Я могу разобраться.
Теперь, когда элемент вставлен, и ему необходимо создать новый узел, что он делает это
_Node_type __node = _Alloc_traits::allocate(_M_get_Node_allocator(), 1);
который я предполагаю, выделяет пространство для одного узла. Но тогда он делает это
::new(__node) _Rb_tree_node<_Val>;
, который я действительно не знаю, что он делает, так как пространство для __node
уже выделены. Но после того, что он также делает этот
_Alloc_traits::construct(_M_get_Node_allocator(), __node->_M_valptr(), ...);
, что делает меня еще более запутанным, потому что якобы строит узел (это аллокатор узла), но он передает указатель __node->_M_valptr()
который имеет типа _Val*
.
Если бы кто-нибудь мог это объяснить, я был бы очень благодарен.
«Оператор new» не выделяет память, он создает объект (а иногда и выделяет память, но не в вашем случае). Итак, я бы сказал, что вторая строка (':: new (__ node) _Rb_tree_node <_Val>;'), вероятно, создает узел в выделенном блоке памяти '__node' – alexeykuzmin0
Хорошо, но зачем передавать указателю' __node' оператору? Кроме того, если он создает узел, что делает ':: construct()' после? – gmardau
«Зачем пропускать указатель»? Как объясняют ответы, это синтаксис _placement 'new'_. И как еще он узнает, где _place___new'_? –