Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ reference changes when push_back new element to std::vector

I am not sure what to make of this - please tell me what's wrong with the code below. I modified my code to reduce it to the simplest terms. There is a std::vector with a bunch of MyNode objects. The first step is to get a constant reference to one of the data elements of one of these nodes (Data m_data) - in the example below, there is only one node before the 2nd node is inserted as seen below:

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

At exactly the vector::push_back call, the value of currData changes!! I just don't get it. How can inserting a new node to the vector change the value reference to the data of the first node?!! Note that the value doesn't change upon "creating" the 2nd node - but upon the insertion operation into the std::vector. I mean, I suppose std::vector may reshuffle some memory, but that shouldn't change the reference right??

Compiler = VS 2012

Thanks guys. Much appreciated.

like image 789
Phoeniyx Avatar asked Oct 25 '13 10:10

Phoeniyx


People also ask

What does the std::vector Push_back () method do?

vector::push_back() push_back() function is used to push elements into a vector from the back. The new value is inserted into the vector at the end, after the current last element and the container size is increased by 1.

Does std::vector Push_back make a copy?

Yes, std::vector<T>::push_back() creates a copy of the argument and stores it in the vector. If you want to store pointers to objects in your vector, create a std::vector<whatever*> instead of std::vector<whatever> .

Does Push_back copy or move?

When inserted using the push_back, the new element is copy-or-move-constructed. The insertion could be inefficient if the passed argument to the push_back is a temporary because the temporary is constructed, copied/moved, and destroyed.

Does Push_back increase size of vector?

push_back effectively increases the vector size by one, which causes a reallocation of the internal allocated storage if the vector size was equal to the vector capacity before the call.


2 Answers

How can inserting a new node to the vector change the value reference to the data of the first node?!!

Because the elements of a vector are stored in a contiguous array. When there's no more room in the array, all of the elements are moved to a larger one, invalidating all iterators, pointers and references to them.

I suppose std::vector may reshuffle some memory, but that shouldn't change the reference right??

Of course it would. A reference refers to a particular object at a particular address; it does not track the object if it's moved.

If you need stable references, then use deque; or (if possible) use reserve to set the vector's capacity large enough to contain everything you might add. References are only invalidated when reallocation is needed, and that only happens when you try to grow beyond the current capacity.

Alternatively, you could store the index of the object, rather than a reference to it.

like image 183
Mike Seymour Avatar answered Oct 19 '22 10:10

Mike Seymour


When you add a new item to a vector, the data in it may be reallocated to fit the new item. This means that references and pointers to the items (and their members) will be invalid.

like image 41
Some programmer dude Avatar answered Oct 19 '22 08:10

Some programmer dude