When std::vector
gets full, new memory is allocated. From what I read, the new capacity grows in a geometric progression (but this is irrelevant to the question), then the old information is copied in the new memory region, and the old one is freed.
Based on this assumption, my questions are:
Why don't compilers try to see if there's enough contiguous free-to-use memory at the end of our std::vector
, allocate just a portion at the end of our std::vector
, and don't waste time copying?
Did people try to implement this, but it was decided it's not worth to do it? (on the average/always)
Are there are any other, more subtle, reasons why this is not happening?
Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location. This reallocation of elements helps vectors to grow when required.
Yes, the elements of a std::vector are guaranteed to be contiguous.
First of all contiguous memory means a chunk of memory allocated without any gaps in the addresses it occupies. It will be one single "block" of memory. Contiguous memory in C++ would mean various ways of allocating contiguous memory in C++. One simple way is arrays as in C.
It is a combination of your points 2) and 3).
First it was reasoned (I cannot say how much measuring has been done at the time) that the benefits were rare and not so great. You can only (significantly) grow memory iff no allocation happened after the origninal allocation, and the cost of growing a vector is amortized.
However many have pointed out that even this scenario is not so rare, and can significantly improve performance and prevent memory fragmentation. So there was a proposal in 2006.
This is were the more subtle reasons kicked in. The first problem is that Containers do not allocate memory by themselfs, but use an Allocator to do so. So as a first step the allocator interface would need to be changed. This is difficult because, as others have noted, realloc can only be used if the contained type is trivial. To be generally useful we would need a different low level function to grow memory (one that reallocates only if it can be done inplace, see the proposal for details). The problem there is that not all platforms provide such a function, and so we would need Posix or the C standard to provide one first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With