我找不到能给出明确答案的任何内容。我只是好奇如果std :: vector只在绝对必须时重新分配它的内部数组,或者它会在预期中提前重新分配(可以这么说)。
例如:
std::vector<int> myVector;
for (int i = 0; i < 1000; ++i) myVector.push_back(i);
cout << myVector.size() << '\n' // Gives 1000 as expected
<< myVector.capacity() << endl; // Gives 1024 which makes sense
如果我继续添加元素,是否有可能我添加的下24个项目中的一个会改变容量,或者只有在我放入第25个项目后它才会重新分配?
注意:
我确实在Linux下使用gcc 4.4.3进行了测试,但似乎重新分配是“按需”完成的,但我很好奇我是不是很幸运,或者是否有某些地方说明这是预期的行为。
答案 0 :(得分:16)
来自C ++标准23.2.4.2:
size_type capacity() const;
返回:向量可以容纳的元素总数,无需重新分配。
同样来自标准
注意:重新分配使引用中的元素的所有引用,指针和迭代器无效 序列。在调用之后发生的插入期间,保证不会发生重新分配 reserve()直到插入使向量的大小大于大小的时间 在最近一次调用reserve()中指定。
所以是的,你可以肯定。
编辑:正如@Bo Persson所提到的,有一个问题。如果我们从不致电reserve()
,标准不会说什么。但是在实践中它运行良好,因为如果你调用reserve,没有实现会记住。我相信这是错误。正如@Martin在C ++ 0x草案中的回答中提到的那样,它已被纠正。
答案 1 :(得分:9)
来自标准:n3092:草案C ++ 0x
23.3.6.2载体容量[载体容量]
void reserve(size_type n);
2效果:一种指令,通知向量计划的大小更改,以便它可以相应地管理存储分配。在reserve()之后,如果重新分配,capacity()大于或等于reserve的参数;并且等于capacity()的先前值。 当且仅当当前容量小于reserve() 的参数时,才会发生重新分配。如果抛出非CopyConstructible类型的移动构造函数以外的异常,则没有效果。23.3.6.4向量修饰符[vector.modifiers]
备注: 如果新大小大于旧容量 ,则会导致重新分配。如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。如果除了复制构造函数之外抛出异常,移动构造函数,赋值运算符或T的移动赋值运算符,或者通过任何InputIterator操作都没有效果。如果非CopyConstructible T的移动构造函数抛出异常,则效果未指定。
答案 2 :(得分:6)
如果您查看cplusplus.com上的push_back文档,请说明:
这有效地增加了向量 大小一,导致一个 重新分配内部分配 存储,如果矢量大小相等 到之前的矢量容量 呼叫。重新分配使所有人失效 以前获得的迭代器, 引用和指针。
所以我非常怀疑在此之前尺寸会发生变化,但你可以随时测试它。至少在我的平台上,尺寸如上所述改变:
size vs capacity
1020 vs 1024
1021 vs 1024
1022 vs 1024
1023 vs 1024
1024 vs 1024
1025 vs 2048
答案 3 :(得分:2)
但是矢量也有容量,它决定了它们分配的存储空间量,并且可以等于或大于实际大小。不使用分配的额外存储量,但保留用于在其增长的情况下使用的向量。这样,向量不必在每次增长时重新分配存储,而只是在这个额外空间耗尽并且插入新元素时(这应该只发生在与其大小相关的对数频率上)。
答案 4 :(得分:2)
std :: vector会根据需求增加容量重新分配 - 即超出当前容量时(size() == capacity()
时)。
将添加多少容量,具体取决于实现:通常为new_capacity = old_capacity * factor
,其中factor
介于1.5到2之间(理论上理想等于Golden section)。这样做是为了将新元素推回到向量中将分摊常量时间。
答案 5 :(得分:0)
标准保证哪些调用不会使迭代器失效。从技术上讲,std::vector
只能通过执行不需要将数据复制到新位置的调整大小来符合标准,即不会使迭代器无效。不过,我怀疑是否有人这样做。
因此,调用reserve()
或resize()
或任何其他被记录为使迭代器无效的调用都会发生调整。
答案 6 :(得分:0)
http://www.sgi.com/tech/stl/Vector.html州
将重新分配内存 自动如果超过容量() - 将size()元素插入向量中。重新分配没有 改变大小(),也不改变 向量的任何元素的值。 但它确实增加了容量(), 它使任何迭代器无效[5] 那指向矢量。
答案 7 :(得分:0)
我发现这些笔记很有帮助:
http://www.sgi.com/tech/stl/Vector.html#2
http://www.sgi.com/tech/stl/FAQ.html (为什么向量在执行重新分配时会将其存储扩展两倍?)
但是,这是SGI STL,找不到g ++文档。