Why does std :: deque allocate memory for its elements in the default constructor?

With g ++ 5.4 compiler and GNU standard library libstdC ++. so.6, the default constructor std::vector creates an empty container that initializes only the internal accounting data elements on the stack. It allocates a heap buffer for data items later (when the first item is inserted). Until recently, I thought this was the usual behavior for any standard sequential container with dynamically allocated memory.

However, std::deque works differently. Tracking the following code

 #include <deque> int main() { std::deque<int> d; return 0; } 

with ltrace gives

 __libc_start_main(0x4024fa, 1, 0x7ffd088be0f8, 0x405bd0 <unfinished ...> _ZNSt8ios_base4InitC1Ev(0x608351, 0xffff, 0x7ffd088be108, 160) = 0 __cxa_atexit(0x401f20, 0x608351, 0x608210, 0x7ffd088bded0) = 0 _Znwm(64, 8, 0, 8) = 0x7b4c20 _Znwm(512, 128, 0, 128) = 0x7b4c70 _ZdlPv(0x7b4c70, 0x7b4c70, 128, 0x7b4c70) = 1 _ZdlPv(0x7b4c20, 0x7b4c20, 8, 0x7b4c20) = 0 _ZNSt8ios_base4InitD1Ev(0x608351, 0, 0x401f20, 0x7fc6d4567d10) = 0x7fc6d4b00880 +++ exited (status 0) +++ 

_Znwm is an implementation of operator new (see this ). Given the internal structure of std::deque and the line #define _GLIBCXX_DEQUE_BUF_SIZE 512 from the header of the STL implementation bits/stl_deque.h , we can conclude that _Znwm(64, 8, 0, 8) selects the std::deque map for 8 pointers and _Znwm(512, 128, 0, 128) allocates one fragment of 512 bytes.

The question arises: what is the reason not to delay the allocation of these 512 bytes until the first element is inserted into std::deque ?

+6
source share
2 answers

The most likely reason is that if the implementation did not execute, all push_back (), push_front (), begin (), end (), insert () would have to check if the block of page pointers is highlighted, and if not executed selection of a block of pointers + on the first page. This conditional check slows down these operations, and the number of these operations is likely to overshadow the instances of the deque executable constructor.

The implementation decided to align the minimal block of pointers +, possibly a blank page. In fact, it looks like a sentry.

Do you really want these common member functions to be slower?

+1
source

Actually according to the standard (and summarized cppreference ), the default constructor

 explicit deque( const Allocator& alloc = Allocator() ); 

The default constructor. Creates an empty container.

If your specific compiler decided that the default constructor implementation would allocate some memory, then this was a specific implementation option for this.

0
source

Source: https://habr.com/ru/post/1011625/


All Articles