簡體   English   中英

C ++中的分配器用法(STL樹)

[英]Allocator usage in C++ (STL Tree)

我最近一直試圖理解c ++分配器是如何工作的,我一直在尋找STL庫用於std::setstd::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>;

這種新表達形式稱為“放置新”。 它不分配新內存,而只構造參數指向的內存區域中的對象。 這里__node是指向已經為節點分配的內存的指針,該表達式在這個地方構造一個_Rb_tree_node<_Val>類型的對象。

_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM