Home > Mobile >  Erasing the last element from the vector, causes problems in iterating
Erasing the last element from the vector, causes problems in iterating

Time:12-15

Here's my code:

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
v.push_back(7);

for (vector<int>::iterator it = v.begin(); it != v.end();   it)
{
    if (*it == 7)
        v.erase(it);
    cout << *it << endl;
}

The issue is, the for loop does not stop running and prints garbage values. Can you give some insight on the issue...like maybe the last element stores information about size or the address of the end()?

Using the erase() method works fine for other locations in the vector, except the last element.

The console log shows garbage values like this:

34603778
35652354
50397954
34603592
34603536
34603536
34603536
34603536
34603794
36700688
34603536
34603536
34865684
51511824
34603536
34865680

CodePudding user response:

Your program has undefined behavior no matter what position you erase from in your vector. As the documentation says, the function:

Invalidates iterators and references at or after the point of the erase, including the end() iterator.

So, your iterator is dead the moment you erase. This is why the function returns a new iterator (to the item that is now in the position you just erased from). You must update your loop's iterator to use that.

The idiomatic way to erase from a standard container in a loop is to step the iterator in the loop body itself:

for (vector<int>::iterator it = v.begin(); it != v.end(); )
{
    if (*it == 7) {
        it = v.erase(it);
    } else {
        cout << *it << endl;
          it;
    }
}

However, this is not a great way in general to remove items from a vector. What if the vector contains lots of values to remove? Your operation becomes very inefficient, because each erase must shuffle the remaining items in the vector.

So the better approach is the erase-remove idiom:

v.erase(std::remove(v.begin(), v.end(), 7), v.end());

Since C 20, this is simplified further:

std::erase(v, 7);
  • Related