Does an unused STL container allocate memory?
C++ Reference With C++17 the default constructor is noexcept
iff the allocator construction is noexcept
. So it depends on the used allocator. In VS 2015 the standard constructor is noexcept
.
Clarification: It means that if the allocator is no noexcept
then no block of memory is allocated.
And for your second question: Same reference, its is O(1).
- If nothing is ever added to the above vector or map, will either still allocate a block of memory for potential entries? (In other words, does entry allocation always happen during container creation or can it be deferred until calls to functions like push_back?)
That can happen, yes. It's actually a detail of the container implementation and not specified in the standard.
- Is there a standard for handling the timing of initial STL container allocation or is that behavior allowed to vary between STL containers and compilers?
You can defer the creation using e.g. a std::unique_ptr
for the members, and create them with a call to a getter function.
Standard doesn't say anything about it, but the implementation I've looked specifically at will do some pre-alocations for std::vector
, and will not pre-allocate anything for std::map
.
This actually once hit me prety hard, when I hade a huge container, which elements had a miniscule - no more than 10 elements, most entries had 0-sized vectors - vector in it. Default vector capacity in this implementation was 32, and '32 * sizeof(vector_element) * number_of_elements' happened to be extremely big.
As mentioned before, this is not well defined. However, you can just test it.
For example with gcc/linux. Make a simple program, compile it with -O0 -g
and run it in gdb. Then
break main
run
break malloc
cont
Now simply run a backtrace
on every malloc and you will see dynamic allocation. With my gcc 5.3.0, both empty containers do not allocate heap memory, this is done on the first push_back
/ operator[]
.
Of course you should use your preferred debugger and break on your allocators underlying function, if that is not gdb
/ malloc
.
Now if you think about the two cases. Would it make sense to pre-allocate memory in that case?
std::vector<int> foo;
foo.push_back(13);
Well, technically you might save a check for nullptr
, but with the usual way to implement vectors as 3 pointers there is no need for an extra check.
But consider
std::vector<int> foo;
foo.reserve(100);
In this case it would be harmful to performance to pre-allocate.
I can find no argument for pre-allocation for a tree-structure such as map.
Please remember, this is a very specific optimization. Optimize for this only with good reason (benchmark!).
Note: You may want to read about small string optimization, a very common technique that is related but different.