Chinaunix

标题: vector erase 问题 [打印本页]

作者: hu_lu_wa    时间: 2013-09-27 16:43
标题: vector erase 问题
网上不是说 下面的会出错吗 ,我的怎么正常啊。



我的怎么不会出异常啊。




帮忙看下 。
作者: linux_c_py_php    时间: 2013-09-27 17:47
连续写2个6你就知道为什么了.
作者: kdkgod    时间: 2013-09-27 17:51
mark,知道会出错的原因,但是不知道为啥不出错的原因。回复 1# hu_lu_wa


   
作者: kdkgod    时间: 2013-09-27 17:51
mark,知道会出错的原因,但是不知道为啥不出错的原因。回复 1# hu_lu_wa


   
作者: yinglj    时间: 2013-09-27 18:14
gdb看一下或vec的地址信息打印看一下,关键是要理解itor在erase时的指针变化及容器本身是否会重构。
不然用反向迭代器删除元素更晕了
作者: folklore    时间: 2013-09-27 20:33
回复 1# hu_lu_wa


只有在iterator被重置时才会出错。 至于iterator什么时候被重置, 要做试验才知道。
可以试试
  1. set a ={0,1 ... 100}
  2. vector b _{0,1 ... 100}

  3. foreach(b as it){
  4.    if( it in a){
  5.         erase(it);
  6.    }
  7. }
复制代码

作者: cxytz01    时间: 2013-09-28 10:36
回复 3# kdkgod

请问哪句话会出错,看不出来。


   
作者: kdkgod    时间: 2013-09-28 10:39
erase(iter++); 必须++, 否则将iter删除了,此时iter不知道该指向哪里。回复 7# cxytz01


   
作者: kdkgod    时间: 2013-09-28 10:42
If the removed elements include the last element in the container, no exceptions are thrown (no-throw guarantee).
Otherwise, the container is guaranteed to end in a valid state (basic guarantee).
An invalid position or range causes undefined behavior.


http://www.cplusplus.com/reference/vector/vector/erase/
回复 7# cxytz01


   
作者: kdkgod    时间: 2013-09-28 10:55
vector<int> veci;
veci.push_back(1);
veci.push_back(2);
veci.push_back(3);
veci.push_back(4);
veci.push_back(5);
veci.push_back(3);
veci.push_back(2);
veci.push_back(3);
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             veci.erase(iter);
}
乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。回复 7# cxytz01


   
作者: kdkgod    时间: 2013-09-28 11:24
找到一篇文件,这个解释的相当详细。看上去不错,值得分享!


http://blog.csdn.net/lanbing510/article/details/8796048
回复 1# hu_lu_wa


   
作者: cxytz01    时间: 2013-09-28 15:36
回复 10# kdkgod


哦,谢谢。在<<c++ primer>>中找到了。


   
作者: Frahm    时间: 2013-09-28 19:48
本帖最后由 Frahm 于 2013-09-28 19:49 编辑

把你的for里的++iter去掉,在内部if后面加个else再++iter就对了。erase会返回下一个迭代器,如果删除了的话,赋值就相当于已经+1了,其他情况下就要显式++iter

现在你这个相当于,删掉6后,跳过了7,直接检查后面的,潜在的逻辑错误




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2