user4120401
user4120401

Reputation: 21

Re-using iterator after 'insert' into vector

I need some clarification regarding vector and iterator. I have a vector of my_object, and an iterator for that vector. I perform an insert at the iterator position, and a second insert at the same location:

myiteratornew = (my_vector).insert(myiterator, my_object1);
myiteratornew = (my_vector).insert(myiterator, my_object2);

After using several times this function on several kind of 'input' data, today I get a memory error. Of course I think the problem is caused by the use of the old iterator on the modified (reallocated) vector; modifying the code this way now it works:

myiteratornew = (my_vector).insert(myiterator, my_object1);
myiteratornew = (my_vector).insert(myiteratornew , my_object2);

My question is, how is it possible that I used my code several times without getting the memory error? Should the second code prevent my code causing a memory error?

Upvotes: 1

Views: 903

Answers (3)

nwp
nwp

Reputation: 9991

What you are supposed to do is insert all objects at once. The iterator is invalid afterwards, but since you inserted everything already you don't need it anymore. Also it is more efficient, since you need to move the objects behind the iterator only once and not multiple times.

my_vector.insert(myiterator, begin(my_objects), end(my_objects));

In case your objects are not in a container you can put them there:

my_object1;
my_object2;

std::reference_wrapper<decltype(my_object1)> myobjects[] = {my_object1, my_object2};

Upvotes: 0

SingerOfTheFall
SingerOfTheFall

Reputation: 29966

If inserting a value into the vector will cause its size to become bigger that its capacity, a reallocation will happen. In this case, all iterators and references are invalidated.

Otherwise, only the iterators and references before the insertion point remain valid. The iterators and references after the insertion point, as well as past-the-end iterator are invalidated as well.

That is most likely what happens to you - you are trying to use an iterator that is no longer valid. That is also why your second example is working as expected - getting a new iterator, and inserting by it is the exactly right thing to do.

Upvotes: 5

MikeCAT
MikeCAT

Reputation: 75062

Using std::list instead of std::vector may free you from getting memory error.

Upvotes: -2

Related Questions