还是list链表的问题

koko2710 2008-07-29 09:59:17
源代码如下
for (list <LoginSession>::iterator it = playerInfo.begin (); it != playerInfo.end (); it ++)
{
cout<<"playerInfo.size()==="<<playerInfo.size()<<"(*it).t_area="<<(*it).t_area<<endl; if ( (*it).t_area == areacode )
{
playerInfo.erase ( it) ;
}
}

红色部分打印出来的结果是
playerInfo.size()===1(*it).t_area=10
playerInfo.size()===0(*it).t_area=12795892

既然容器内容是0了,怎么还会循环进来?
...全文
114 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
koko2710 2008-07-30
  • 打赏
  • 举报
回复
我不是删一个 是只要符合要求的全删,不管几个
某鸟 2008-07-29
  • 打赏
  • 举报
回复
这个问题我几天前弄过……
不过我用的是it = xxx.erase(it);
...
tlzhu 2008-07-29
  • 打赏
  • 举报
回复
在for循环中对列表的元素进行增删,是一种不良风格,应该尽量避免。
其实楼主的代码在g++3.4.6中是不会出问题的,而在vc7.1下就出现了楼主所说的问题。可见,各编译器厂商对这个问题的处理不尽相同,所以这么写很可能带来移植性问题。

如果要删除list中的一个元素,可以采用下面的方法:

string areacode;
bool equal(playerInfo& p)
{
return p.t_area == areacode;
}

int main()
{
areacode = "001";
list<playerInfo> l;

...

l.remove_if(equal);

return 0;
}
guzhilei1986 2008-07-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 txwcan999 的回复:]
for (list <LoginSession>::iterator it = playerInfo.begin (); it != playerInfo.end (); )
{

cout < <"playerInfo.size()===" < <playerInfo.size() < <"(*it).t_area=" < <(*it).t_area < <endl;

if ( (*it).t_area == areacode )
{
playerInfo.erase ( it) ;
if ( it != playerInfo.end () )
it++;//////我觉得这里好像有点问题吧
else
break;
}

}
[/Quote]
我觉得改成这样就可以了。
if ( (*it).t_area == areacode )
{
playerInfo.erase ( it) ;
}
else it++;
koko2710 2008-07-29
  • 打赏
  • 举报
回复
for (list <LoginSession>::iterator it = playerInfo.begin (); it != playerInfo.end (); )
{

cout < <"playerInfo.size()===" < <playerInfo.size() < <"(*it).t_area=" < <(*it).t_area < <endl;

if ( (*it).t_area == areacode )
{
playerInfo.erase ( it) ;
if ( it != playerInfo.end () )
it++;
else
break;
}

}
不行的,红色的地方已经把it的数据清空了
下面再++,还是原来的地址,没变。
txwcan999 2008-07-29
  • 打赏
  • 举报
回复
for (list <LoginSession>::iterator it = playerInfo.begin (); it != playerInfo.end (); )
{

cout < <"playerInfo.size()===" < <playerInfo.size() < <"(*it).t_area=" < <(*it).t_area < <endl;

if ( (*it).t_area == areacode )
{
playerInfo.erase ( it) ;
if ( it != playerInfo.end () )
it++;
else
break;
}

}
txwcan999 2008-07-29
  • 打赏
  • 举报
回复
for (list <LoginSession>::iterator it = playerInfo.begin (); it != playerInfo.end (); )
{

cout < <"playerInfo.size()===" < <playerInfo.size() < <"(*it).t_area=" < <(*it).t_area < <endl;

if ( (*it).t_area == areacode )
{
playerInfo.erase ( it) ;
}
// 关键是erase()后有可能到达playerInfo.end (),这时候不能it++; 这里判断了两次,不知有没有更换的方法?
if ( it != playerInfo.end () )
it++;
else
break;

}
txwcan999 2008-07-29
  • 打赏
  • 举报
回复
你的列表里头只有一个数据, 当删除一个后, it到达list的末尾了, 在it++ 之前, 应该判断下释放到list 末尾:
if ( it != playerInfo.end () )
it++;
else
break;
koko2710 2008-07-29
  • 打赏
  • 举报
回复
for (list <LoginSession>::iterator it = playerInfo.begin (); it != playerInfo.end ();)
{
if ( (*it).t_area == areacode )
{
playerInfo.erase ( it++) ;
}else{
++it;
}
}
修改后问题解决。
erase后it指向的地址已经变了,再++已经不是链表下一个元素的位置了对吧。
至于removed,不会。。。。
某鸟 2008-07-29
  • 打赏
  • 举报
回复
erase完了,iterator还可以++的啊?
学到了……
hai040 2008-07-29
  • 打赏
  • 举报
回复
list删除特定值直接调用remove就行了
hai040 2008-07-29
  • 打赏
  • 举报
回复
erase后it失效,所以在erase前要先++
for(...;...;)
{
...
if (...)
playerInfo.erase(it++);
else
++it;
}
koko2710 2008-07-29
  • 打赏
  • 举报
回复
昏,当然知道是有错,没错跑着问干嘛,既然知道就请指点一下。
hai040 2008-07-29
  • 打赏
  • 举报
回复
因为这段代码是错误的

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧