调整STL矢量的大小是否会擦除/使其以前的内容无效

Does resizing an STL vector erase/invalidate its previous contents?

本文关键字:无效 STL 调整 是否 擦除      更新时间:2023-10-16

(示例程序)似乎没有,但我能确定吗?

// does resizing an STL vector erase/invalidate it's previous contents?
#include <stdio.h>
#include <vector>
using namespace std ;
void print( vector<int>& t )
{
  for( int i = 0 ; i < t.size() ; i++ )
    printf( "%d ", t[i] ) ;
  puts("");
}
int main()
{
  vector<int> t ;
  t.resize( 12,9999 ) ;
  print(t) ;
  t.resize( 15, 10000 ) ;
  print(t) ;
}

调整STL向量的大小可能需要重新分配底层存储。此可能导致任意数量的元素被销毁和重新创建,并且所有迭代器都将无效使用STL时,访问无效迭代器是常见的错误源。

除非复制构造函数不起作用,否则每个元素的内容都是相同的。

int main(int argc, char *argv[])
{
    int data[] = { 1, 2, 3 };
    std::vector vec(data, data + 3);
    // vector contains 1, 2, 3
    std::vector::iterator i = vec.begin();
    cout << *i << endl; // prints 1
    int &ref = *i;
    cout << ref << endl; // prints 1
    vec.resize(6, 99);
    // vector now contains 1, 2, 3, 99, 99, 99
    // WRONG! may crash, may do the wrong thing, might work...
    // cout << *i << endl;
    // WRONG! invalid reference
    // cout << ref << endl;
    return 0;
}

resize将使所有迭代器、指针和对std::vector的引用无效,如果且仅当新大小大于容器的当前容量(即v.capacity())。

容器中的元素永远不会"无效"。如果将容器大小调整为小于当前大小,则超过新大小的任何额外元素都将被销毁。

如果调整容器的大小,使新的大小大于当前容量,并且需要重新分配底层存储,则所有元素都会复制或移动到新分配的存储中。当您放大容器时,以前的元素总是被保留,只是被移动或复制到内存中的新位置。

调整向量的大小不会破坏存储在向量中的值(当然,收缩时超过新大小的值除外),但是,将向量增长到其容量之外会将它们复制(或在C++11中移动)到新的位置,从而使这些元素的迭代器、指针或引用无效。

在您的示例程序中,在调整大小期间不存储迭代器、指针或对矢量元素的引用,因此,如果数据在调整大小期间被复制,则可以访问复制的值(这很可能,但并不完全确定;向量可能会为超过所需的元素分配空间;事实上,在增长时,必须这样做才能满足复杂性要求)。

您可以通过成员函数capacity获得当前容量(在需要重新分配之前可以将其增长到的元素数量)。只要向量不超过当前容量,即使是迭代器、指针和对存储对象的引用也是安全的。此外,如果您想确保没有迭代器、指针或引用无效,并且您事先知道向量可能增长到的最大大小,那么您可以使用成员函数reserve预先分配所有需要的内存。

Resize会根据需要复制数据。看看这个http://www.cplusplus.com/reference/stl/vector/resize/

内容仍然存在。如果向量的容量为1000,其中包含500个元素,并且将大小调整为2000,则所有500个元素都将被复制。如果将其大小调整为200,则只复制前200个元素,并删除最后300个元素。

这里有一个例子。

当您将大小调整为更大的大小时,它只会用值填充新的单元格。