[英]Allocator usage in C++ (STL Tree)
我最近一直試圖理解c ++分配器是如何工作的,我一直在尋找STL庫用於std::set
或std::map
類的紅黑樹的實現,但是有一些我無法理解的事情。
首先要做的是將分配器從容器必須存儲的類型 - _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(__node) _Rb_tree_node<_Val>;
使用placement new
,它只是在給定的內存地址__node)
構造一個_Rb_tree_node<_Val>
類型的對象。 這構造了節點對象。
現在它需要與_M_valptr()
一個成員做一些事情。 這條線
_Alloc_traits::construct(_M_get_Node_allocator(), __node->_M_valptr(), ...);
(間接調用)分配器的construct
方法 ,它非常類似於全局布局new
(事實上,它通常只是調用它)。 因此,它再次獲取指向構造對象的位置的指針。 這構造了值對象。
它使用了一種名為“ Placement New ”的東西,它允許在已經分配的內存中構造一個對象。
void * mem = malloc(sizeof(MyStruct));
MyStruct * my_struct_ptr = new(mem) MyStruct(/*Args...*/);
/*Do stuff...*/
my_struct_ptr->~MyStruct();//Literally one of the only times a good programmer would ever do this!
free(mem);
或者你可以像這樣寫:
char * mem = new char[sizeof(MyStruct)];
MyStruct * my_struct_ptr = new(mem) MyStruct(/*Args...*/);
/*Do stuff...*/
my_struct_ptr->~MyStruct();//Literally one of the only times a good programmer would ever do this!
delete mem;
或這個:
char mem[sizeof(MyStruct)];
MyStruct * my_struct_ptr = new(mem) MyStruct(/*Args...*/);
/*Do stuff...*/
my_struct_ptr->~MyStruct();//Literally one of the only times a good programmer would ever do this!
基本思想是,您現在負責通常由語言和編譯器自動處理的手動清理。 在使用分配器時, 除了內存分配的直接控制對於編寫好的分配器至關重要,這是非常糟糕的做法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.