简体   繁体   中英

Iterating through a vector and erasing

It is obvious for many that this code will produce a segment fault.

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::vector<int> ints;
    ints.push_back(5);
    std::vector<int>::iterator it;
    for(it = ints.begin(); it != ints.end(); ++it){
        std::cout << *it;
        it = ints.erase(it);
    }
}

If we remove the ++it and add a condition to erase, we can avoid this error. But what is the actual cause of the issue? In our loop we say, for the start of the iterator, until it reaches the end, incrementing by one, print out the value and then erase it. Is it because the ++it is called at the "end" when, in this condition, we've already removed the next (only) value?

Is it because the ++it is called at the "end" when, in this condition, we've already removed the next (only) value?

Yes.

std::erase returns an iterator to the element after the one that was erased.

Consider a vector with only a single element, then your loop is basically:

it = ints.begin(); 
std::cout << *it;
it = ints.erase(it);    // it == ints.end()
++it;                   // boom
//if (it != ints.end()) // more boom

See here: Is it allowed to increment an end iterator? - No.

Such problems are one reason to prefer the erase-remove-idiom rather than a hand-written loop to erase elements.

Your assumption is mistaken. Let me quote the relevant part:

In our loop we say, for the start of the iterator, until it reaches the end , incrementing by one , print out the value and then erase it.

That description swaps the two bold parts, and it is important. The increment is done before the check if it reached the end. That's wrong when erasing the last element. In that case, your iterator is already at the end, and you still increment it before checking if it reached the end.

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