我有这段代码:
for (std::vector<Marker>::iterator it = markers.begin(); it != markers.end(); ++it) {
if (it->getDots().size() < 3) {
markers.erase(it);
}
}
在其中一个测试输入中(应用程序进行图像分析)我得到了段错误。我试图调试代码(无济于事)并注意到一件事。在向p markers.size()
询问gdb时,我收到$9 = 3
。所以我希望循环迭代三次,但令人惊讶的是它(至少)完成了5次。在第五次迭代中有一个段错误。我还注意到,导致错误的*it
(此处it->
)的解除引用并非如此。它具体是it->getDots()
,这是一个简单的吸气剂。
我很少用C ++编写,所以这可能是一个简单的错误,但我的调试和谷歌搜索都没有带来任何解决方案。你能帮忙吗?
我想强调的是,在各种不同的输入(略有不同的图像)上,这个功能正常工作,所以我更难以追踪这个错误。
答案 0 :(得分:6)
vector::erase
使指向要删除的元素的所有迭代器以及后面的所有元素无效。因此it
变为无效,并且下一循环迭代中的++it
表达式表现出未定义的行为。
编码此逻辑的最佳方法是使用erase-remove idiom。
答案 1 :(得分:3)
问题在于这一行:
markers.erase(it);
迭代器无效。但是没关系,erase
返回一个有效的迭代器:
auto it = markers.begin();
while(it != markers.end())
{
if(it->getDots().size() < 3) {
it = markers.erase(it);
}
else ++it;
}
答案 2 :(得分:2)
删除时需要更新it
:
it = markers.erase(it);
因为erase
将“更改”vector
,而您当前的it
不再有效(如果您没有删除它,则只会it++
) 。
但是,更常见的方法是使用这种结构:
markers.erase(std::remove(markers.begin(), markers.end(), number_in), markers.end());