Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

With g++ 5.4 compiler and GNU standard library libstdc++.so.6, default constructor of std::vector creates an empty container initializing only internal bookkeeping data members on stack. It allocates buffer on heap for data elements later (when the fist element is inserted). Until recently, I thought it was a common behavior for any standard sequential container with dynamically allocated memory.

However, std::deque works differently. Tracing 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 (please see this). Considering the internal structure of std::deque and the #define _GLIBCXX_DEQUE_BUF_SIZE 512 line from STL implementation header bits/stl_deque.h, one may conclude that _Znwm(64, 8, 0, 8) allocates std::deque's map for 8 pointers and _Znwm(512, 128, 0, 128) allocates one chunk of 512 bytes.

The question is: what is the reason not to postpone allocating these 512 bytes until the first element in std::deque is inserted?

like image 273
ktrushin Avatar asked Oct 23 '16 13:10

ktrushin


People also ask

Does default constructor allocate memory?

A constructor does not allocate memory for the class object its this pointer refers to, but may allocate storage for more objects than its class object refers to. If memory allocation is required for objects, constructors can explicitly call the new operator.

Why are pointers dynamic memory allocated?

The size of the problem often can not be determined at “compile time”. Dynamic memory allocation is to allocate memory at “run time”. Dynamically allocated memory must be referred to by pointers. the computer memory which can be accessed by the identifier (the name of the variable).

Is deque contiguous in memory?

The standard contiguous-memory containers are vector, string, and deque.

Is std :: deque sorted?

The math behind them not withstanding, std::deque has random access iterators, and as such any in-place sorting algorithm will be able to sort the data within using that functionality and not requiring O(N) additional storage. std::list doesn't provide random access iteration, and thus is not std::sort -able.


1 Answers

The most likely reason is that if the implementation did not do, every push_back(), push_front(), begin(), end(), insert() would have to check to see if the block of pointers to pages is allocated, and if not execute allocation of the block of pointers + the first page. That conditional checking slows these operations down, and the number of these operations is likely to dwarf the instances of a deque constructor executing.

The implementation has decided to stump up a minimum block of pointers + possibly an empty page. Effectively it is like a sentinel.

Would you really rather these common member functions be slower?

like image 75
SJHowe Avatar answered Sep 22 '22 14:09

SJHowe