C++迭代器失效问题(insert、erase)

 

什么是迭代器

  迭代器提供了一种方法,使它能够按照顺序访问某个容器所含的各个元素,但无需暴露该容器的内部结构,换句话说迭代器就是指针的简单包装,通过一个模板类封装的对象

 

 

迭代器的失效问题

 

一、迭代器在vector、deque等内存连续的容器删除中失效


  对于序列式容器,比如vector,删除当前的iterator会使后面所有元素的iterator都失效。这是因为顺序容器内存是连续分配(分配一个数组作为内存),删除一个元素导致后面所有的元素会向前移动一个位置。(删除了一个元素,该元素后面的所有元素都要挪位置,所以,iter++,已经指向的是未知内存)。


二、迭代器在map\set\mutilset等关联类的容器中删除不失效

 

  在关联类容器(map\set\mutilset)删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。

 

 

三、迭代器在内存连续的容器中插入元素,插入位置之前的迭代器有效,之后的迭代器失效;内存非连续得容器插入迭代器不失效

 

  insert插入没有返回值,因此insert不能在循环中 连续的 进行插入操作(插入位置之后的迭代器失效,无法遍历)

  

 

 

  

 

注意: 正常使用erase删除迭代器是有返回值的,返回的是下一个有效的迭代器,

 

 

#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>
#include<future>
using namespace std;

int main()
{
    std::vector<int>v{ 0, 1, 2, 3 };

    for (auto i = v.begin(); i != v.end(); i++)
    {
        //cout << *i << endl;
        i=v.erase(i);//迭代器i被删除之后是一个无效的迭代器(nullptr指针),因此不能对i进行任何操作;
        //erase()返回值指向下一个迭代器
        cout << *i << endl;  
    }
    system("pause");
    return 0;
}

 

 

 

vector::const_iterator 和 const vector::iterator的区别

  前者不能修改容器中的元素,如:*newiter=11 属于错误,可以修改迭代器自身,如:newiter++正确;后者可以修改指向容器的元素,如:*newiter=11正确,迭代器本身不能被修改,如:newiter++错误;

 




posted @ 2020-08-13 11:12  知道了呀~  阅读(3800)  评论(0编辑  收藏  举报