STL中迭代器失效问题

迭代器失效有两个层面的意思

  • 无法通过迭代器++,–操作遍历整个stl容器。记作: 第一层失效。
  • 无法通过迭代器存取迭代器所指向的内存。 记作: 第二层失效。

造成失效的两个函数

  • insert(i, value)
    在迭代器i前插入一个元素value, 返回指向value迭代器
  • erase(i)
    删除迭代器i位置的元素, 返回指向后一个元素的迭代器

避免失效的方法

  • i = insert(i, value)
  • i = erase(i)

  • 对于迭代器失效,可以分为数组型、链表型、树型结构几种结构来说。

数组型

对于vector、deque等连续存储的容器来说,插入元素(insert)或者删除元素(erase),会导致后边的迭代器都失效,解决方法是,erase(*iter)会返回下一个有效迭代器的值,删除元素时用将当前迭代器赋值为erase的返回值,系统会自动将迭代器的指向修改的。

for (iter = cont.begin(); iter != cont.end();)
{
   (*it)->doSomething();
   if (shouldDelete(*iter))
      iter = cont.erase(iter);  //erase删除元素,返回下一个迭代器
   else
      ++iter;
}

迭代器失效

void vectorTest()
{
    vector<int> container;
    for (int i = 0; i < 10; i++)
    {
        container.push_back(i);
    }

    vector<int>::iterator iter;
     for (iter = container.begin(); iter != container.end(); iter++)
    {
            if (*iter > 3)
              container.erase(iter);
    }

     for (iter = container.begin(); iter != container.end(); iter++)
    {
            cout<<*iter<<endl;
    }
}

报错是:vectoriterator not incrementable.
但是erase方法可以返回下一个有效的iterator。所以代码做如下修改,就OK了。

void vectorTest()
{
    vector<int> container;
    for (int i = 0; i < 10; i++)
    {
        container.push_back(i);
    }

    vector<int>::iterator iter;
     for (iter = container.begin(); iter != container.end(); iter++)
    {
            if (*iter > 3)
              iter = container.erase(iter);
            else
              iter++;
    }

     for (iter = container.begin(); iter != container.end(); iter++)
    {
            cout<<*iter<<endl;
    }

链表型

对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

树型结构

对于map,set,multimap,multiset来说, 使用红黑树来存储数据,插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器.

猜你喜欢

转载自blog.csdn.net/ZWE7616175/article/details/81836448