Стирает ли изменение размера вектора STL его предыдущее содержимое? - PullRequest
9 голосов
/ 07 марта 2012

Это не похоже на (пример программы), но могу ли я быть уверен?

// 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) ;
}

Ответы [ 6 ]

18 голосов
/ 07 марта 2012

Изменение размера вектора 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;
}
7 голосов
/ 07 марта 2012

resize сделает недействительными все итераторы, указатели и ссылки в std::vector тогда и только тогда, когда новый размер больше текущей емкости контейнера (т. Е., v.capacity()).

Элементы в контейнере никогда не считаются недействительными. Если вы измените размер контейнера, чтобы он был меньше его текущего размера, любые дополнительные элементы за пределами нового размера будут уничтожены.

Если вы измените размер контейнера так, чтобы новый размер был больше, чем текущая емкость, и требуется перераспределение базового хранилища, все элементы копируются или перемещаются во вновь выделенное хранилище. Когда вы увеличиваете контейнер, предыдущие элементы всегда сохраняются, просто перемещаются или копируются в новые места в памяти.

2 голосов
/ 07 марта 2012

Изменение размера вектора не уничтожает значения, хранящиеся в векторе (за исключением тех, которые выходят за рамки нового размера, конечно, при уменьшении), однако при увеличении вектора до его емкости копирование (или, в C ++ 11, перемещение ) их на новое место, что делает недействительными и итераторы, указатели или ссылки на эти элементы.

В вашем примере программы вы не сохраняете итераторы, указатели или ссылки на векторные элементы во время изменения размера, поэтому вы получаете доступ к скопированным значениям, если данные были скопированы во время изменения размера (что вероятно, но не полностью определено; вектор может выделять место для большего количества элементов, чем нужно; более того, при его увеличении должно сделать это для выполнения требований сложности).

Вы можете получить текущую емкость (количество элементов, на которое вы можете увеличить ее до того, как потребуется перераспределение) через функцию-член capacity. Пока вектор не выходит за пределы текущей емкости, даже итераторы, указатели и ссылки на хранимые объекты безопасны. Кроме того, если вы хотите убедиться, что никакие итераторы, указатели или ссылки недействительны, и вы заранее знаете максимальный размер, до которого может расти вектор, то вы можете предварительно выделить всю необходимую память с помощью функции-члена reserve.

0 голосов
/ 07 марта 2012

Вот пример Здесь .

Когда вы изменяете размер до большего, он просто заполняет новые ячейки значением.

0 голосов
/ 07 марта 2012

Содержимое все еще будет там.Если ваш вектор имеет емкость 1000, с 500 элементами в нем, и вы изменяете размер до 2000, все ваши 500 элементов будут скопированы.Если вы измените его размер до 200, будут скопированы только первые 200 элементов, а последние 300 будут удалены.

0 голосов
/ 07 марта 2012

Resize копирует данные на сколько угодно.Взгляните на это http://www.cplusplus.com/reference/stl/vector/resize/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...