随笔 - 132  文章 - 51  trackbacks - 0
<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿(7)

随笔分类

随笔档案

文章分类

文章档案

cocos2d-x

OGRE

OPenGL

搜索

  •  

最新评论

阅读排行榜

评论排行榜

遍历一个容器同时删除这个容器的迭代器,会使这个容器失效
来看下什么是迭代器, 任何特定的迭代器都是某个类型的对象,vectorr的迭代器可以被实现为一个到vector的指针,加一个下标
表的迭代器可以是一个指向链表的指针, 所有迭代器的共同之处在于它们的语义,以及它们的有关操作的名字。
eg.迭代器++操作总是产生引用下一个元素的迭代器, *总是产生这个迭代器引用的那个元素,基本上符合这些的都可以成为迭代器了

常用的遍历删除迭代器方法,拿map举例
  map<intint> mp;
    
forint i = 0; i < 10++i )
    {
        mp[i] 
= i;
    }

    map
<intint>::iterator iter = mp.begin();
    
while( iter != mp.end() )
    {
        
if ( iter->first < 10 )
        {
            mp.erase( 
iter++ );        
        }
         else
        {
            
++iter;
        }
    }
在删除时记录下下一个有效的迭代器就OK了

如果用同样的方法使用在vector上就崩了,这个是为什么呢

vector<int> vec;
    
forint i = 0 ;i < 20++i )
    {
        vec.push_back( i );
    } 

    vector
<int>::iterator it = vec.begin();
    
while( it != vec.end() )
    {
        
if ( *it < 10 )
        {
           
 vec.erase( it++ );      // 导致崩溃        
        }
        else
        {
            
++it;
        }
    }

这是因为vector和list,map删除迭代器后结果不一样, 因为map, list删除迭代器后,只有当前删除的迭代器无效, it++就可以获得下一个有效的迭代器了,但是vector 删除迭代器后,
当前删除的迭代器之后的所有迭代器都会失效

正确方法
#include <windows.h>
#include 
<map>
#include 
<string>
#include 
<list>
#include 
<vector>
#include 
<algorithm>
using namespace std;

bool gt_val( int val )
{
    
return val%2 == 0 ? true : false;
}

int main()
{
    vector
<int> vec;
    
forint i = 0 ;i < 20++i )
    {
        vec.push_back( i );
    }
    
    
// 标准库调用方法
    vector<int>::iterator it = vec.begin();
    
while( (it = find_if( it, vec.end(), gt_val))!= vec.end() )
    {
        it 
= vec.erase( it );
    }

    
// 普通调用方法
    it = vec.begin();
    
while( it != vec.end() )
    {
        
if ( *it < 10 )
        {
           
 it = vec.erase( it );        
        }
        else
        {
            
++it;
        }
    }
    
    
    map
<intint> mp;
    
forint i = 0; i < 10++i )
    {
        mp[i] 
= i;
    }

    map
<intint>::iterator iter = mp.begin();
    
while( iter != mp.end() )
    {
        
if ( iter->first < 10 )
        {
          
  iter = mp.erase( iter );        
        }
        else
        {
            
++iter;
        }
    }

}

posted on 2011-11-08 17:33 风轻云淡 阅读(685) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理