Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1466631
  • 博文数量: 218
  • 博客积分: 6394
  • 博客等级: 准将
  • 技术积分: 2563
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-08 15:33
个人简介

持之以恒

文章分类

全部博文(218)

文章存档

2013年(8)

2012年(2)

2011年(21)

2010年(55)

2009年(116)

2008年(16)

分类: C/C++

2010-07-18 15:16:05


循环中使用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连续存储来说,就删除一个元素的时候不需要将迭代器++了.
阅读(4140) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

GilBert19872010-07-20 09:43:14

哦,是的,看了下MSDN iterator erase( iterator _Where ); iterator erase( iterator _First, iterator _Last ); Return Value For the first two member functions, a bidirectional iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the hash_map if no such element exists.

chinaunix网友2010-07-19 09:20:41

i = m_ws.erase(i); 也行的