Can't figure out vector incompatible iterators problem
I wrote this code:
Code:
int arr[] = {10,20,30,40,50};
static std::vector<int> nums(arr, arr+sizeof(arr)/sizeof(arr[0]));
std::vector<int>::iterator it = nums.begin();
std::vector<int>::iterator en = nums.end();
for ( ; it != en ; ++it) {
it = nums.erase(it);
}
Second iteration I get "vector iterators incompatible", during != operator.
Can anyone say what's wrong?
Re: Can't figure out vector incompatible iterators problem
not positive here, but can end() change when you erase?
I always see this loop as
Code:
for (it = nums.begin(); it!=nums.end(); it++)
{
}
Also,
Code:
it = nums.erase(it);
Then, in your for loop, you have it++
Won't this skip one?
Re: Can't figure out vector incompatible iterators problem
Quote:
Originally Posted by
jnmacd
not positive here, but can end() change when you erase?
Any vector iterator can be invalidated when you erase.
Regards,
Paul McKenzie
Re: Can't figure out vector incompatible iterators problem
Quote:
Originally Posted by
gmeir11
I wrote this code:
Code:
int arr[] = {10,20,30,40,50};
static std::vector<int> nums(arr, arr+sizeof(arr)/sizeof(arr[0]));
std::vector<int>::iterator it = nums.begin();
std::vector<int>::iterator en = nums.end();
for ( ; it != en ; ++it) {
it = nums.erase(it);
}
Second iteration I get "vector iterators incompatible", during != operator.
Can anyone say what's wrong?
"en" no longer points to end(), as erasing items in a vector invalidates iterators.
Secondly, why not just call clear() if you want to erase all the elements?
Regards,
Paul McKenzie
Re: Can't figure out vector incompatible iterators problem
Does that mean
Code:
it = nums.begin();
nums.erase(it);
it++;
is not valid?
Re: Can't figure out vector incompatible iterators problem
Quote:
Originally Posted by
jnmacd
Does that mean
Code:
it = nums.begin();
nums.erase(it);
it++;
is not valid?
When the element in the vector(unlike std::list or deque) is erased, all the references of the iterators starting from the position erased no longer point to the same memory block. The rationale behind this is to keep the efficiency of the vector's performance, particularly the reallocation of the contigious memory block.
What this mean is that if a loop starts erasing from the index[0], then all iterators are invalidated because no valid iterators can possibly have existed before the first. Likewise, If a loop starts erasing from the end, then all iterators are still valid unless the user purposedly assign iterators to the invalid range to begin with, thus,
Code:
for ( ; it != en; --en)
{
nums.erase(en - 1);
}
will likely not cause runtime error.
For this reason, it is recommended to move the element to the back and pop it which is typically done with std::remove() preceeded by vector::erase()