We often need to delete some elements in an STL set. But it causes a strange bug if we are careless sometimes.
One newbie in C Plus Plus program language may write the following code to delete all odd numbers in a set.
int main()
{
vector<int> vec{ 1, 3, 5, 7, 8, 9, 10 };
vector<int>::iterator it;
for( it = vec.begin(); it != vec.end(); ++it )
{
if( *it & 1 )
{
vec.erase( it );
}
}
for_each( vec.begin(), vec.end(), []( int &element ){ cout << element << " "; } );
cout << endl;
return 0;
}
The above example output result:
3 7 8 10
The operation erases
deletes one element from the vector, after that it moves all rest elements forwards to fill the empty position. So the iterator jumps two elements after erase
and ++it
, a few elements will be omitted and not detected.
We can solve the problem by the following method, store all even numbers in a new vector object and swap both finally.
int main()
{
vector<int> vec{ 1, 3, 5, 7, 8, 9, 10 };
vector<int> vec2;
for_each( vec.begin(), vec.end(), [&vec2]( int element ){ if( !(element&1) ){
vec2.push_back( element );
} } );
vec.swap( vec2 );
for_each( vec.begin(), vec.end(), []( int &element ){ cout << element << " "; } );
cout << endl;
return 0;
}