std::vector 何时重新分配其内存数组?

2021-12-21 00:00:00 vector c++ stl

我找不到任何可以给出明确答案的内容.我只是好奇 std::vector 是否仅在绝对必须或将在预期中提前重新分配时才重新分配其内部数组(可以这么说).

例如:

std::vector我的向量;for (int i = 0; i <1000; ++i) myVector.push_back(i);cout<<myVector.size() <<'
'//按预期给出 1000<<myVector.capacity() <<结束;//给出 1024,这是有道理的

如果我继续添加元素,我添加的接下来 24 个项目中的一个是否有可能改变容量,或者只有在我放入第 25 个项目后才会重新分配?

注意:

我确实在 Linux 下使用 gcc 4.4.3 运行了一个测试,但是似乎重新分配是按需"完成的,但我很好奇我是否只是幸运,或者是否有什么地方表明这是预期行为.

解决方案

来自 C++ 标准 23.2.4.2:

size_type capacity() const;

<块引用>

返回:向量在不需要重新分配的情况下可以容纳的元素总数.

也来自标准

<块引用>

注意:重新分配会使所有引用、指针和迭代器中的元素失效.顺序.保证在调用之后的插入过程中不会发生重新分配Reserve() 直到插入将使向量的大小大于大小的时间在最近一次对reserve() 的调用中指定.

所以是的,你可以确定.

正如@Bo Persson 提到的,有一个问题.如果我们从不调用 reserve() ,标准就不会说什么.然而在实践中它运行良好,因为没有实现会记住你是否调用了reserve.我相信这是错误.正如@Martin 在他在 C++0x 草案中的回答中提到的那样,它已得到纠正.

I can't find anything that gives a definitive answer. I was just curious if a std::vector reallocate its internal array only when it absolutely must or will it reallocate ahead of time in anticipation (so to speak).

For example:

std::vector<int> myVector;
for (int i = 0; i < 1000; ++i) myVector.push_back(i);

cout << myVector.size() << '
'      // Gives 1000 as expected
     << myVector.capacity() << endl; // Gives 1024 which makes sense

If I continue to add elements, is there ever any chance that one of the next 24 items I add will change the capacity or will it only reallocate once I put in a 25th item?

Note:

I did run a test using gcc 4.4.3 under Linux, but and it seems like the reallocation is done "on-demand", but I was curious if I was just lucky or if there is something somewhere stating that this is expected behavior.

解决方案

From C++ standard 23.2.4.2:

size_type capacity() const;

Returns: The total number of elements that the vector can hold without requiring reallocation.

Also from Standard

Notes: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the size specified in the most recent call to reserve().

So yes, you can be sure.

Edit: As @Bo Persson mentioned there is a catch. Standard doesn't say anything if we never call reserve() . However in practice it works well, because no implementation will care to remember if you called reserve, or not. I believe that this is bug. And as @Martin mentioned in his answer in C++0x draft it is corrected.

相关文章