矢量迭代次数比size()

时间:2013-08-10 18:24:15

标签: c++ iterator std stdvector

我有这段代码:

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 ++编写,所以这可能是一个简单的错误,但我的调试和谷歌搜索都没有带来任何解决方案。你能帮忙吗?

我想强调的是,在各种不同的输入(略有不同的图像)上,这个功能正常工作,所以我更难以追踪这个错误。

3 个答案:

答案 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());