Когда std :: vector увеличивается, адреса к элементам в нем больше не действительны?

Предположим, у меня есть следующее:

struct Foo {
Foo () : bar(NULL), box(true) {}
Bar* bar;
bool box;
};

и я заявляю следующее:

std::vector<Foo> vec(3);

У меня есть функция, которая делает что-то вроде этого:

Foo& giveFoo() { //finds a certain foo and does return vec[i]; }

Затем вызывающий абонент передает адрес Foo он получает по ссылке как Foo* к другому парню. Что мне интересно, однако, если этот указатель на Foo останется в силе после запуска вектора в vec? Если существующий Foo элементы в vec затем копируются предположительно Foo* что плавало теперь будет болтаться? Это так или нет? Я отлаживаю приложение, но не могу воспроизвести это.

2

Решение

Любые указатели или ссылки на элементы будут недействительными, когда вектор будет перераспределен, как и любые итераторы.

5

Другие решения

Указатель будет оставаться действительным до тех пор, пока вы не вызовете неконстантную функцию-член для вектора, которая:

  • заставляет его размер превышать его емкость (когда это произойдет, внутреннее хранилище будет
    перераспределить и все указатели и ссылки на элементы будут признаны недействительными) или

  • вставляет элемент перед элементом, на который указывает указатель, или

  • удаляет элемент из вектора, или

  • удаляет элемент из вектора, который был расположен перед элементом, на который указывает указатель.

Первые две пули могут произойти одновременно. Разница в том, что ссылки / указатели на элементы, расположенные до точки вставки, остаются действительными, пока размер не превышает емкость.

3

Да, это может стать недействительным, потому что в основном, когда vector нужно увеличить зарезервированный размер, он просто удаляет свое внутреннее хранилище (которое в основном является массивом), выделяет увеличенное и копирует туда свое предыдущее содержимое.

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

1

Ниже то, что стандарт говорит о валидности векторных итераторов для векторных модификаторов:

vector::push_back(), vector::insert(), vector::emplace_back(), vector::emplace():

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

vector::erase():

Делает недействительными итераторы и ссылки в или после точки удаления.

Любое предположение за пределами этого небезопасно.

1
По вопросам рекламы [email protected]