+ 2
[SOLVED] Erasing vector items adds thousands of items. Where did I go wrong?
Hi SoloLearmers, So I'm just practicing on how to erase ranges from a vector and I have a problem. Allow me to describe it. - First there's a vector<int> with 5 items - I create an iterator named <it> which refers to the last element. That is the 5th element. - I add 20 new elements to the vector - I erase data in range, from vector begin() to <it> - I see the vector has thousands of elements Please point me what did I do wrong? enlighten me. Thank you, in advance ... https://code.sololearn.com/cNpxPX41cNwU/?ref=app (Edit) A working version, ditching the iterator idea altogether https://code.sololearn.com/cvnNaQ817Zgb/?ref=app
5 Answers
+ 2
You're invalidating the iterator after you insert new values.
In this case it triggered a reallocation when you added new values.
You'd want to use &*it to get the actual address of the underlying value of the iterator, otherwise you'll just get the address of the iterator itself on the stack.
How did the vector increase in size? No idea, I would have to take a look at the implementation.
More specifically what happens when the 2nd iterator's address is less than the 1st iterator for the erase function.
But if we take a look at the address of your iterator, and the address of the first element in the vector, in my case:
it: 0x669e80
vi.begin(): 0x66af70
and take the difference: 4336 ( in base 10 )
now divide that by the size of an int in a 64 bit system (4): 1084
add the original 25 elements: 1109
Which was the exact size of the vector after erasing. Coincidence, or...? :)
Erase is probably updating the internal end variable to the difference between the 2 iterators. Since the 2nd iterator is less than the 1st iterator it gets a negative value which caused the function to add to the end variable instead of subtract. But that's just my guess.
+ 1
Dennis,
Thank you so much 🙏
You're right, the iterator is no longer valid past the items addition. That must've been the reason for this behaviour .
It works fine after I understood it, and changed (reassign) <it> to a new address just before the erase() was invoked.
But now I think of another question. How do I correctly "save" the address of the 5th element (the last element before items addition), so that I can use it later on, in this case, to erase the 1st up to the 5th item after addition of the 20 new items : )
+ 1
Dennis,
Nevermind, come to think of it, the idea of keeping an address which will only be invalidated later on, was a stubborn dumb idea LOL 😁
+ 1
Yup, the only way you can do that with a vector is if you know the size of the vector and reserve that size upfront in order to prevent it from having to reallocate when you insert new elements.
But then again, it's just as fast to access the 5th index anyway. ^^
+ 1
Dennis,
I was thinking to just save the initial size of the vector (5) to a variable e.g. <saved_size>, and later on use it like so ...
vi.erase( vi.begin(), vi.begin() + saved_size );
I don't think I want to prevent the vector to grow (reallocate) though, to me it's ability to grow & shrink is one of its strengths.