【发布时间】:2011-03-14 06:16:09
【问题描述】:
代码:
for(x=abc.begin();x!=abc.end();x++)
{
if(-----)
{
----
abc.erase(x);
}
}
错误是:::
危险的迭代器用法
擦除后迭代器无效,因此取消引用或将其与另一个迭代器进行比较是无效的。
上述代码中使用擦除功能有什么错误?
【问题讨论】:
代码:
for(x=abc.begin();x!=abc.end();x++)
{
if(-----)
{
----
abc.erase(x);
}
}
错误是:::
危险的迭代器用法
擦除后迭代器无效,因此取消引用或将其与另一个迭代器进行比较是无效的。
上述代码中使用擦除功能有什么错误?
【问题讨论】:
从 abc 中删除对应的值后,iterator x 无效。这应该可以解决它:
x = abc.begin();
while(x != abc.end())
{
if (-----)
{
----
x = abc.erase(x);
// skipped only to next item
}
else
{ // skip only to next item
++x;
}
}
STL 容器的erase 模板函数返回下一个元素,即end()。
编辑:感谢 templatetypedef 的评论。
【讨论】:
x 迭代器在那些被删除的元素之后。
您在循环中使用 x 作为控制变量。由于它被 erase() 无效,因此您无法确定随后在循环顶部递增它是否安全(或有意义)。
【讨论】:
x 是指向abc 的指针。删除x 指向的项目后,x 应该指向什么以及x++ 应该如何工作?
【讨论】:
您对正在迭代的容器只字未提。容器的类型取决于哪些迭代器无效。确保擦除元素的迭代器无效,但例如在std::vector all 中,过去擦除元素的迭代器将无效(包括end())。并且由于未知原因,尽管set::erase 仅使擦除元素的迭代器无效,但它不会将迭代器返回到下一个元素。
所以std::set:
while (x != abc.end()) // end() will not change and even can be stored
{
if (...)
abc.erase(x++); // increments before erasing
else
++x;
}
【讨论】: