STL的erase()陷阱-迭代器失效总结

作者:ca88编程

STL中list的erase()方法,stllisterase方法

erase()方法是去除iterator钦赐的节点  不过要留神的是在实践完此函数的时候iterator也被灭绝了   这样的话关于iterator的操作就能够报错     以下是有关erase()方法的不错采纳

科学生运动用方法1 :  

图片 1

std::list< int> List;
std::list< int>::iterator itList;
for( itList = List.begin(); itList != List.end(); )
{
    if( WillDelete( *itList) )
    {
        itList = List.erase( itList);
    }
    else
    {
        itList  ;
    }
}

图片 2

没有错接纳格局2:

图片 3

std::list<int> List;
std::list<int>::iterator itList;
for( itList = List.begin(); itList != List.end(); )
{
    if( WillDelete( *itList) )
    {
        List.erase( itList  );
    }
    else
    {
        itList  ;
    }
}

图片 4

不当采取办法1:

图片 5

std::list< int> List;
std::list< int>::iterator itList;
for( itList = List.begin(); itList != List.end(); itList  )
{
    if( WillDelete( *itList) )
    {
        List.erase( itList);
    }
}

图片 6

 

谬误选拔方法2:

图片 7

std::list< int> List;
std::list< int>::iterator itList;
for( itList = List.begin(); itList != List.end(); )
{
    if( WillDelete( *itList) )
    {
        itList = List.erase(   itList);
    }
    else
        itList  ;
}

图片 8

 相同的时候要留心的是    std::list  八线程不安全的,所以八线程对list操作一般都要加锁,保障安全性

erase()方法是删除iterator内定的节点 可是要小心的是在实践完此函数的时候iterator也被销毁了 那样的...

       或

1.3 错误写法1

1 std::list< int> List;
2 std::list< int>::iterator itList;
3 for( itList = List.begin(); itList != List.end(); itList  )
4 {
5      if( WillDelete( *itList) )
6      {
7           List.erase( itList);
8      }
9 }

例如有贰个列表 ShipList,里面的原委是0、1、2、3...9, 倘使要从中删除这几个取余3后为0或为1的数,删除后应当吸取的结果是 2、5、8。 
但一旦是那般操作: 
std::<int >::iterator it; 
for( it = ShipList.begin(); it != ShipList.end(); it ) 

if( (*it) % 3 == 0 || (*it) % 3 == 1) 
ShipList.erase( it ); 

那样的话会有三个难点,二个是近水楼台先得月的结果是 1、2、4、5、7、8(未有去除取余3后等于1的数);其他多个难题是当实行到列表中最后多少个因素(即ShipList.end()

3.13 multimap

键能够不独一。
另外特点与map一样。

     在选取vector、deque遍历删除成分时,也能够通过erase的再次来到值来获得下三个要素的地点:

3.3 list

里头数据结构:双向环状链表。
无法随意拜望三个因素。
可双向遍历。
在起来、末尾和中路任哪个地方方扩充或删除成分所需时日都为常量。
可动态扩充或回退成分,内部存款和储蓄器管理活动完毕。
追加其余因素都不会使迭代器失效。删除成分时,除了指向当前被删去成分的迭代器外,其它迭代器都不会失效。

颠倒是非采用格局2      std::list< int> List;
      std::list< int>::iterator itList;
      for( itList = List.begin(); itList != List.end(); )
      {
            if( WillDelete( *itList) )
            {
               itList = List.erase( itList);
            }
            else
               itList ;
      }

3.11 hash_multiset

键能够不独一。
别的特点与hash_set相同。

  • 1 )时,迭代器恐怕还可能会施行一回“ ”,假如是那样那么it就达到了 ShipList.end() 1 的地方,那样也会报错。

3.12 map

键唯一。
要素暗中认可按钮的升序排列。
借使迭代器所指向的因素被删去,则该迭代器失效。别的任何扩张、删除成分的操作都不会使迭代器失效。

不错利用方式2      std::list< int> List;
      std::list< int>::iterator itList;
      for( itList = List.begin(); itList != List.end(); )
      {
            if( WillDelete( *itList) )
            {
               List.erase( itList );
            }
            else
               itList ;
      }

3.7 priority_queue

适配器,它能够将随机档案的次序的行列容器调换为多少个预先级队列,一般选拔vector作为底层存款和储蓄格局。
唯其如此访谈第三个要素,不能够遍历整个priority_queue。
先是个要素始终是优先级最高的三个要素。

      正确使用办法1:通过erase方法的再次来到值来赢得下三个元素的职分
      正确选拔方法2:在调用erase方法以前先使用 “ ”来获得下两个要素的职位
      错误采用方法1:在调用erase方法之后选取“ ”来猎取下贰个要素的岗位,由于在调用 erase方法之后,该因素的任务已经被删除,假诺在依照那一个旧的地点来赢得下叁个位置,则会出现非常。
      错误采用形式2:同上。

3.迭代器失效的场所

erase( itList ) 是先得到下贰个要素的职分再删除; erase( itList) 是去除以往再拿到下三个因素的职位。 
自个儿觉着,erase(itList )是itList先传递值给erase(),然后再自增;
erase( itList) 是先自增,然后再把自增后的值传递给erase(),那个是失误的发源。

1.list,set,map容器

     在采纳 list、set 或 map遍历删除有些因素时能够那样使用:

         或

1.5 分析

不容置疑利用方法1:通过erase方法的重返值来获得下四个要素的职位
不错使用办法2:在调用erase方法以前先使用 “ ”来收获下三个因素的地点
不当选取办法1:在调用erase方法之后选用“ ”来博取下三个因素的职分,由于在调用erase方法之后,该因素的职位已经被删除,假若在依赖那几个旧的地方来得到下三个岗位,则会出现十分。
荒唐选择方法2:同上。

本文由ca88发布,转载请注明来源

关键词: ca88网址 yzc88亚洲城娱乐 C++/C C++