Why does std::vector reserve not "double" its capacity, while resize does?
As far as I can tell, neither resize
nor reserve
is required to have the demonstrated behaviour. Both are however allowed such behaviour although both could either allocate the exact amount, and both could multiply the previous allocation as far as the standard is concerned.
Each allocation strategies have their advantages. The advantage of allocating exact amount is that it has no memory overhead when the maximum allocation is known beforehand. The advantage of multiplying is that it maintains the constant amortized property when mixed with end-insertion operations.
The approach chosen by the tested implementations has the advantage that it allows both strategies when resizing. To use one strategy, one can reserve and then resize. To use the other, just resize. Of course, one has to be aware of the unspecified behaviour to take advantage of this. This advantage may or might not be the reasoning behind the choice of these implementations.
One might consider it a failure of the vector API, as specified in the standard, that expressing the intended reallocation behaviour is not possible (in a way that is guaranteed by the standard).
When you resize
more than there is capacity you already "demonstrate" that you don't want to reserve just the right capacity. On the other hand, if you use reserve
you explicitly ask for the right capacity. If reserve
would use the same strategy as resize
there would be no way to reserve just the right amount.
In this sense resize
without reserve
is for the lazy ones or in case you don't know the exact amount to reserve. You call reserve
if you know what capacity you need. That's two different scenarios.
PS: As StoryTeller pointed out, also reserve
is not required to reserve the exact amount that is asked for as per the standard. Nevertheless I think my main argument still holds: resize
(without reserve
) and reserve
are meant for different scenarios, where you either give a hint of how much you want to reserve or don't care about the actual capacity and just want to have the container sized to what you ask for.
Why would you expect them to behave the same? reserve
is used to preallocate space you will use later, with the expectation that the user has a decent handle on the expected final size of the container. resize
is simply a normal allocation, and so it follows the normal, speed efficient, approach of geometrically increasing the container's allocated space.
Containers increase in size by multiplicative steps to reduce the number of allocations needed and thus maintain speed and reduce memory fragmentation. Doubling is the most common, but some implementations use steps of 1.5 (e.g. MSVC) which trade increased allocations for lower wasted space within each container.
But, if the user has already told the library how big they think the container will get - by causing reserve
- there's no need to allocate excess space, they can instead trust the user to have called it with the correct number. It is reserve
that has the unusual behaviour, not resize
.