Ссылка C ++ изменяется при push_back нового элемента на std :: vector

Я не уверен, что с этим делать - скажите, пожалуйста, что не так с приведенным ниже кодом. Я изменил свой код, чтобы сократить его до простейших терминов. Есть std :: vector с кучей объектов MyNode. Первый шаг - получить постоянную ссылку на один из элементов данных одного из этих узлов (данные m_data) - в приведенном ниже примере есть только один узел до того, как будет вставлен второй узел, как показано ниже:

const cv::Data& currData = m_nodesVector[currIndex].GetData();
MyNode node(...);
m_nodesVector.push_back(node);

Точно при вызове vector :: push_back значение currData изменяется !! Я просто не понимаю. Как может вставка нового узла в вектор изменить ссылку значения на данные первого узла? !! Обратите внимание, что значение изменяется не при «создании» 2-го узла, а при операции вставки в std :: vector. Я имею в виду, я полагаю, что std :: vector может перетасовать некоторую память, но это не должно изменить ссылку правильно ??

Компилятор = VS 2012

Спасибо ребята. Очень признателен.


person Phoeniyx    schedule 25.10.2013    source источник


Ответы (4)


Как может вставка нового узла в вектор изменить ссылку значения на данные первого узла? !!

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

Я полагаю, что std :: vector может перетасовать некоторую память, но это не должно изменить ссылку правильно ??

Конечно, было бы. Ссылка относится к конкретному объекту по определенному адресу; он не отслеживает объект, если он перемещается.

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

В качестве альтернативы вы можете сохранить индекс объекта, а не ссылку на него.

person Mike Seymour    schedule 25.10.2013

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

person Some programmer dude    schedule 25.10.2013

Вы можете обновить указатель при его перемещении через конструктор перемещения:

A(A&& a): b(a.b) { b.ptr  = this; };
person cmdLP    schedule 27.02.2017

Посетите http://www.cplusplus.com/reference/vector/vector/push_back/

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

person Nagappa    schedule 18.07.2018