Препратката към C++ се променя, когато push_back нов елемент към std::vector

Не съм сигурен какво да правя с това - моля, кажете ми какво не е наред с кода по-долу. Модифицирах кода си, за да го намаля до най-простите термини. Има std::vector с куп MyNode обекти. Първата стъпка е да получите постоянна препратка към един от елементите на данни на един от тези възли (Data m_data) - в примера по-долу има само един възел, преди да бъде вмъкнат 2-ри възел, както се вижда по-долу:

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