最近加入了公司的一个移植项目,目标是把原来在PC平台上的程序放到360上运行。客户给的是PC上的代码和数据,编译过后就能够跑了。但是程序运行时,偶尔会报告错误。在VS2010启动的情况下,可以看到Debug游标停在对一个++Iterator的操作上。因为是调试版本,所以代码中额外添加了对Iterator的检查部分,具体信息是:”list iterator notincrementable”。
这个程序原本是在03,04年左右写的,结构还是比较清晰,模块划分也是清楚地按照功能进行,所以了解代码功能还是比较方便的。同时在程序代码中,大量运用了C++ STL模块,错误信息就是从这个部分发出来的:
for ( std::list<*>::iterator it =ObjList.begin(); it != ObjList.end(); ++it )
{
If((*it)->regin == CheckRegin )
{
ObjList.erase(it);
}
}
初看这部分代码,还没有看出错误端倪,感觉不是很正确的么:遍历list并删除目标的元素。后来实在没辄了,上网查了一下资料,才发现是代码在处理Iterator的earse的时候有点问题。当一个Container执行了一次earse操作之后,原来用来遍历的iterator就失效了,其行为是不可预测的,具体情况由实现决定。同时earse操作会返回一个指向container下一个元素的iterator,如果想继续遍历,就得用返回的iterator继续操作。
所以针对上面的代码,如果只是删除遍历时候碰到的第一个符合条件的元素,那么在earse之后添加break,使得不再进行遍历。如果要继续操作,那么就得改成:
for ( std::list<*>::iterator it =ObjList.begin(); it != ObjList.end(); )
{
If((*it)->regin == CheckRegin )
{
it= ObjList.erase(it);
}
else
{
++it;
}
}
如此,那个错误就不再出现了。
之前也看过STL相关的一些资料,以为能用其基本功能了,但真的实践起来还是有不少细节需要注意的。