Summary of several cases of failure of vector iterator

  • 2020-05-10 18:34:09
  • OfStack

Iterators (iterator) undoubtedly play an important role in both generic programming and the actual use of STL. An iterator is a pointer like object (such as content retrieval, member access, etc.), but it is not just a pointer.

Regarding iterator failure, we can take a look at the following example:


#include<vector>
#include<list>
void PrintVector(const vector<int>& v)
{
  vector<int>::const_iterator it = v.begin();
  while (it!=v.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}
void TestIterator()
{
    // Iterator failure 
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(2);
v.push_back(4);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(4);
v.push_back(4);
v.push_back(6);
  vector<int>::iterator it = v.begin();
  while (it != v.end())
  {
    if (*it % 2 == 0)
    {
      it = v.erase(it);
      ++it;
    }
    
  }
  PrintVector(v);
}
void main()
{
  TestIterator();
}

Such code at first 1 to see if there is no problem, but he is problematic, because in vector is stored in order, delete an element in the vector, we need to vector redistribution 1 space, in the old space elements to be copied to the new space, if you remove the element of the iterator can point to one element under after + + it, also is in the copy of time can't find the one element, so can make the delete and delete points after the iterator invalid.

The correct approach is:


vector<int>::iterator it = v.begin();
  while (it != v.end())
  {
    if (*it % 2 == 0)
    {
      it = v.erase(it);
    }
    else
    {
      ++it;
    }
    
  }
  PrintVector(v);

The same is true for adding elements. If there are 10 elements in the current container and you are now adding them to the container, if there is no extra space in memory, vector will need to re-create the space to store the original elements as well as the newly added elements. Copying an element in a new space, inserting a new element, and finally undoing the original space will invalidate all iterators.

Summary: several failure cases of vector iterator:

1. When an element (push_back) is inserted, the iterator returned by the end operation must fail.

2. When an element (push_back) is inserted, the return value of capacity is changed compared with that before the element is inserted. Then the entire container needs to be reloaded, and the iterator returned by first and end operations will fail.

3. When the deletion operation (erase, pop_back) is carried out, all iterators pointing to the deletion point fail; Iterators that point to elements following the delete point will also all fail.


Related articles: