Reputation:
I was trying to use vectors in C++
. I am trying to insert one element using iterator at a specified position and then remove some elements again using iterator.But I get error when using the same iterator for both the operations.Here is my code -
#include <iostream>
#include <vector>
#include <cctype>
using namespace std;
int main()
{
vector <int> A(10);
for (int i=0;i<A.size();i++)
{
A[i]=i+1;
}
vector<int>::iterator p=A.begin();
p+=2;
A.insert(p,1,55);
A.erase(p,p+2);
for (int i=0;i<A.size();i++)
{
cout << A[i] <<"\n";
}
return 0;
}
This gives me the following output:
*** Error in `./temp': double free or corruption (out): 0x00000000017d4040 ***
55
3
4
5
6
7
8
9
10
Aborted (core dumped)
If I add following two lines before A.erase
I get the correct answer.
p=A.begin();
p+=2;
A.erase(p,p+2);
So, if p still points to the same element as its value has not been changed, why do I need to again set the value of p.
Upvotes: 0
Views: 619
Reputation: 49986
According to standard (n4296 C++14) [23.3.6.5/1] insert operation for vector invalidates iterators - but not always:
Remarks: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid.
and for erase [23.3.6.5/3]
Effects: Invalidates iterators and references at or after the point of the erase.
These are rules, behaviour you are seeing as correct is actually UB (undefined behaviour) - which means it might look like it works even if in 99% of times. Also it depends on implementation in your compiler.
Upvotes: 1
Reputation: 12178
after inserting/erasing from std::vector
all existing iterators are invalidated and should not be used (using them will lead to undefined behavior)
remember, that changing items contained by vector may lead to memory allocation etc., so old iterators can point to deallocated memory (like pointers)
So when you add lines you mention and reinitialize iterator - everything is ok. But after insert
existing p
is no longer valid.
Check paragraphs about 'iterator invalidation' in: http://en.cppreference.com/w/cpp/container/vector/erase and http://en.cppreference.com/w/cpp/container/vector/insert.
You might consider adding call to reserve
to ensure that no reallocation happens on insert
but in my opinion such code would still be error prone and harder to maintain.
Upvotes: 3