好的,我有一个我正在迭代的STL参考列表。该功能有三个等效部分。该函数将wstring作为参数,并运行相应的if语句。我已经将代码减少到一个if语句来尝试让它工作。
所以,我检查一下作为参数传递了什么。然后我检查ClassItem是否是某种类型的动物。如果是,我检查它是否饿了,并从列表中删除它。我现在只是想避免seg故障,似乎无法做到。
list<ClassItem *>::iterator i = Items.begin();
while(i != Items.end())
{
if(!AnimalType.compare(L"tiger"))
{
if((*i)->IsAnimalType(L"tiger"))
{
if((*i)->IsHungry())
{
i = Items.erase(i);
}
}
else
{
++i;
}
}
// I have tried removing this
else
{
i++;
}
}
我的印象是当我调用erase时当前迭代器无效。所以,如果我擦除一个元素,我将返回下一个有效的迭代器。我哪里错了?
编辑:谢谢你的快速帮助。问题已得到解决。我已经使用了phresnel的解决方案并且工作得非常好。答案 0 :(得分:3)
使用std::list::remove_if和合适的谓词最好。这完全避免了手动循环,减少了错误的范围,并帮助删除或至少你本地化了问题的根源,因为只要你的谓词可以依赖这个习语是正确的。
bool badAnimal(ClassItem * item)
{
// return true if animal is to be removed
}
Items.remove_if(badAnimal);
答案 1 :(得分:1)
我认为这里没有潜在的段错误。反正:
有(恕我直言)两个可能的问题:
if(!AnimalType.compare(L"tiger"))
这看起来很可疑。什么是AnimalType
?如果if(!AnimalType.compare(L"tiger"))
本身不,您是否真的希望AnimalType
的值在迭代期间发生变化?
在任何情况下,它看起来像一个读取,因此不应该写。它看起来不变,因此不应该改变。
然后:
if((*i)->IsAnimalType(L"tiger"))
{
if((*i)->IsHungry())
{
i = Items.erase(i);
}
// NO ITERATION IN CASE OF NOT HUNGRY.
// ONCE TRAPPED HERE, YOU HAVE AN INFINITE LOOP,
// EXCEPT AnimalType.compare(L"tiger") DOES SOMETHING
// NON-SANE.
}
else
{
++i;
}
这最好是:
if((*i)->IsAnimalType(L"tiger") && (*i)->IsHungry())
{
i = Items.erase(i);
}
else
{
++i;
}
然而,更好的方法是使用标准算法去除元素。
答案 2 :(得分:0)
您可能想要添加
continue;
擦除后。