简体   繁体   中英

Erasing the last element from the vector, causes problems in iterating

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

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM