当调整为较低计数时,在vector :: resize()中重新分配空间?

时间:2012-10-03 11:22:08

标签: c++ stl vector

根据 Stroustrup:C ++编程语言: -

“当 vector 调整大小以容纳更多(或更少)元素时,其所有元素都可能是 搬到了新的地方。“

这是否成立,即使将矢量调整为较小的尺寸?

4 个答案:

答案 0 :(得分:4)

案例1:如果请求的新尺寸大于当前std::vector::capacity(),则所有元素都将重新定位。
案例2:如果请求的新大小小于当前std::vector::capacity(),则不会重新定位元素。


Standerdese Evidence:

该标准将vector::resize()的效果定义为:

C ++ 11标准23.3.6.3/12向量容量:

void resize(size_type sz, const T& c);

效果:

if (sz > size())
     insert(end(), sz-size(), c);
else if (sz < size())
    erase(begin()+sz, end());
else
; // do nothing

正如@DavidRodríguez-dribeas正确指出的,std::vector::insert()操作的迭代器失效规则是:

  

23.3.6.5向量修饰符

     

1 [insert,push_back,emplace,emplace_back]

     

备注:如果新大小大于旧容量,则会导致重新分配。如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。

基本上这意味着: 除非新容器大小大于先前容量,否则插入点之前的所有迭代器和引用都不会受到影响,因为在这种情况下,所有元素都可能被移动到新位置,从而使指针/迭代器无效到原始位置。自 resize()仅在容器末尾删除/插入元素 [注释1] 。管理因素归结为请求的大小与当前容量相对应。

因此案例1结果。

案例2 std::vector::erase()将被调用,此案例中的失效规则为:

  

23.3.6.5向量修饰符

     

迭代器擦除(const_iterator位置);

     

3效果:使擦除点处的在<或>之后>使迭代器和参考值无效。

[注1] 以来,元素只会在结尾删除,不需要重新定位所有元素。

答案 1 :(得分:1)

  

...元素可能会移动到新的位置。“

请注意可能会被移动。所以这意味着它取决于它是什么类型的调整大小。

答案 2 :(得分:1)

向量中的迭代器因两个原因而失效。如果向量需要增加其容量,则在迭代器(1)的位置或整个缓冲区重新定位(2)之前插入/移除元素。这里的关键是对capacity()的更改。

因为resize()仅从容器的末尾插入/删除。当向量收缩时,只有那些引用被删除元素的迭代器才会失效。当向量增长时,如果新大小小于capacity(),则迭代器将无效,并且如果新大小较大,则所有迭代器将无效。

由于Als提供了错误的证据 1 ,我在这里添加了正确的引号:

  

23.3.6.5向量修饰符

     

1 [insert,push_back,emplace,emplace_back]

     

备注:如果新大小大于旧容量,则会导致重新分配。如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。

     

2 [擦除]

     

效果:使擦除点处的在<或>之后>使迭代器和引用无效。

类似的引用可以在C ++ 03中找到。


1 避免复制指示resize与插入或擦除等效的引用。哪个是对的。

答案 3 :(得分:0)

问题正文中的答案“”当向量调整大小以容纳更多(或更少元素时,其所有元素都可能是搬到了新的地方。“”