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