C++ 向量的迭代次数超过size()的次数

C++ 向量的迭代次数超过size()的次数,c++,iterator,std,stdvector,C++,Iterator,Std,Stdvector,我有一段代码: for (std::vector<Marker>::iterator it = markers.begin(); it != markers.end(); ++it) { if (it->getDots().size() < 3) { markers.erase(it); } } for(std::vector::iterator it=markers.begin();it!=markers.end();+it){ 如果(

我有一段代码:

for (std::vector<Marker>::iterator it = markers.begin(); it != markers.end(); ++it) {
    if (it->getDots().size() < 3) {
        markers.erase(it);
    }
}
for(std::vector::iterator it=markers.begin();it!=markers.end();+it){
如果(it->getDots().size()<3){
删除(它);
}
}
在一个测试输入(应用程序进行图像分析)中,我得到一个segfault。我试着调试代码(没有用),但注意到一件事。当要求gdb
p markers.size()
时,我收到
$9=3
。所以我希望循环迭代三次,但令人惊讶的是,它至少迭代了5次。在第五次迭代中,有一个segfault。我还注意到,导致错误的不是
*it
(此处
it->
)的解引用。特别是
It->getDots()
,这是一个简单的getter

我在C++中写得很少,所以可能是一些简单的错误,但是我的调试和Google都没有解决任何问题。你能帮忙吗


我想强调的是,在各种不同的输入(稍有不同的图像)上,此功能正常工作,因此我更难找到错误。

您需要在擦除时更新

it = markers.erase(it);
由于
擦除
将“更改”
向量
,并且您当前的
向量
不再有效(并且只有在未擦除时才执行
it++

但是,更常见的方法是使用这种结构:

markers.erase(std::remove(markers.begin(), markers.end(), number_in), markers.end());

问题在于这一行:

markers.erase(it);
迭代器无效。但没关系,
erase
返回一个有效的迭代器:

auto it = markers.begin();
while(it != markers.end())
{
    if(it->getDots().size() < 3) {
        it = markers.erase(it);
    }
    else ++it;
}
autoit=markers.begin();
while(it!=markers.end())
{
如果(it->getDots().size()<3){
它=标记。擦除(它);
}
否则它;
}

vector::erase
使指向被擦除元素的所有迭代器以及随后的所有元素无效。因此,
it
变得无效,并且在下一个循环迭代中,
++it
表达式表现出未定义的行为


编写此逻辑的最佳方法是使用。

您是迭代操作的受害者。不敢相信internet上有这么多关于迭代器操作的示例,如“迭代器->doSomething()”,但几乎没有人对这种特殊情况发出警告,这可能很常见,因为从集合中删除内容似乎是一项基本的操作。但我的缺点是,我应该更仔细地阅读文档。谢谢你们!确实如此,因为我喜欢把事情讲得冗长,特别是在C++中(我不是专家)。对于处理器来说,它可能会花费更多的时间,但是我的向量最多只有9个元素,所以性能影响不太大。除非他有C++(并且可以使用lambda),否则他需要为其条件定义一个单独的函数或函数对象(并且使用<代码>删除如果)。这可能是合理的,也可能不是合理的,这取决于他申请的其他部分。(根据我的经验,如果你需要测试一次,你通常会在其他地方需要类似的东西,并且通常值得努力定义函数对象。)当然,如果他有C++11,lambda会优雅地解决这个问题。