Chinaunix首页 | 论坛 | 博客
  • 博客访问: 285678
  • 博文数量: 182
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1292
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-06 19:02
个人简介

让一切的准备都完美演出,让所有的努力都美好落幕

文章分类

全部博文(182)

文章存档

2016年(60)

2015年(122)

我的朋友

分类: C/C++

2016-08-31 17:20:23

原文地址:stl中map的erase方法(转) 作者:GilBert1987


循环中使用erase删除map中的元素的时候
1.错误写法
int nFinishedCount = 0;
for( WSIter iter = m_ws.begin(); iter != m_ws.end(); ++iter )
 {
  SchdWorkSheet * pws = iter->second;
  if( pws->completeWorkSheet() )
  {
   destroyWorkSheet(pws);
   m_ws.erase(iter);
   nFinishedCount++;
  }
 }
原因是迭代器的++操作的内部实际都是在操作它保存的节点指针(SGI STL Map的实作应该是红黑树(STL源码剖析)),所以当这个节点被删除的时候,该节点指针指向的内存的数据是无法确定的,也就是可能还是以前正确的数据,也可能已经是其他毫无相关的数据了,这样的行为也就是经常听说的undefined behavior.所以自然出现了,有时候还能正常运行一会儿,有时候就core掉了的情况,果然是undefined...
对于其他的链式存储,都是类似的解释感谢侯捷的《STL源码剖析》,对iterator有了重新理解,实在是好书...
2006 6.15
 
解决的办法是在删除iter指向的内容之前就将其移动到下一个正确地址,所以正确写法如下:
1.正确写法 
 int nFinishedCount = 0;
 for( WSIter i = m_ws.begin(); i != m_ws.end();  )
 {
  SchdWorkSheet * pws = i->second;
  if( pws->completeWorkSheet() )
  {
   destroyWorkSheet(pws);
   m_ws.erase(i++);
   nFinishedCount++;
  }
  else
   ++i;
 }
 
不止是map, 链式存储结构的stl容器都会这样,而对vector. string连续存储来说,就删除一个元素的时候不需要将迭代器++了.
阅读(1385) | 评论(0) | 转发(0) |
0

上一篇:static和volatile的用法

下一篇:grep

给主人留下些什么吧!~~