Что делает получение адреса возврата из std :: vector :: operator []? - PullRequest
2 голосов
/ 26 января 2012

Я делаю что-то вроде:

struct ABC{
int p,q,r;
};

struct X{
ABC *abc;
X(ABC &abc) : abc(&abc) {}
};

std::vector<ABC> vec;
... //populate vec

X x(vec[2]);

Когда я отлаживаю, x.abc выглядит правильно сразу после назначения, но вскоре после этого данные в x.abc становятся мусором. Это заставляет меня думать, что указатель на локальную переменную ... но vector::operator[] возвращает ссылку, так возможно ли это?

1 Ответ

7 голосов
/ 26 января 2012

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

Если вы хотите сохранить указатель на вектор, вы должны быть уверены, что вектор не перераспределяет свой внутренний буфер. Вы можете сделать это либо подождать, пока вы добавите все элементы, которые вы собираетесь добавить в вектор, прежде чем брать ссылки, или вызвать vector::reserve, чтобы убедиться, что емкость достаточно большая.

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

Надеюсь, это поможет!

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