我有一个整数向量,我正在反向遍历。我需要搜索其中的元素并在遍历向量时删除它的第一个匹配项。我正在使用以下功能并获得分段错误
for(i=num.end()-1;i!=num.begin()-1;i--)
{
tmp=binary(*i);
if(tmp!=num.end())
{num.erase(i);num.erase(tmp);res++;}
}
函数binary在这里返回一个迭代器,如果要使用erase函数的语句,它的值肯定小于i。
我使用以下链接: - How to traverse vector from end to start?和 Erasing elements from a vector
但他们建议使用std :: remove和std :: remove_if函数来删除所有出现的值。
答案 0 :(得分:0)
编辑:我错了,你的设计有缺陷。
我忽略的问题:请注意num.erase(x)
使x
之后的元素的引用和迭代器无效。这意味着num.erase(i);num.erase(tmp);
有效tmp < i
,但也意味着i
之后无效。因此,在循环的下一次迭代中,循环迭代器将无效!
如果您只打算擦除这两个元素,则应在擦除后退出循环。如果您打算在端到端扫描中删除多个项目,则需要找到一些方法在最早删除点之前将循环指针前进到点。 (但是,您还应注意,从std::vector<>
中间删除多个项目效率很低 - 通常从长度为N的向量中删除每个O(N)。你也可以退出循环并从最后重新开始(这就是我认为@SHR意味着“重置迭代器”)。
如果您不能执行上述任何操作,则需要一些其他类型的容器,例如std::list<>
,erase()
不会使剩余元素的迭代器无效。此外,这些删除是O(1)(尽管你失去了快速随机访问...)
如果binary()
的行为与你所说的相同,那么你的意图似乎是合理的:来自erase()
的{{1}}元素应该在删除的元素完整之前将引用和迭代器留给元素。< / p>
问题可能在其他地方。如果您发布的代码是逐字的,那么您的std::vector<>
声明中就会出现格式错误:
if
请注意,实际受if(tmp!=num.end())
num.erase(i);num.erase(tmp);res++;
条件影响的唯一语句是if
- 其余语句将无条件执行。具体来说,如果num.erase(i);
,它仍将执行tmp==num.end()
,可能会导致细分错误....
可能的最小修复是在三个语句周围添加花括号:
num.erase(tmp)