我的矢量迭代器出现了一个奇怪的错误

时间:2014-04-26 23:15:39

标签: c++ vector iterator

我有一个向量的迭代器,我想删除向量中的某些元素。运行代码时,编译中没有出现错误,但在执行后我收到一条消息,说“调试断言失败了!”#39;。有人能告诉我迭代器有什么问题吗?

int function(unsigned int n, unsigned int m)
{
vector<int> vec1;

    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);

vector<int>::iterator vec2;

for (vec2 = vec1.begin(); vec2 != vec1.end(); ++vec2)
{
    if(*vec2 == 4)
    {
    vec1.erase(vec2);
    }
}

return 0;
}

4 个答案:

答案 0 :(得分:4)

erase方法会使迭代器无效。你必须写:

for (vec2 = vec1.begin(); vec2 != vec1.end(); )
{
    if(*vec2 == 4)
      vec2 = vec1.erase(vec2);
    else
      ++vec2;
}

请注意,仅当元素不是vec2时,您才必须增加erased。如果在每次迭代时增加vec2,则会遗漏一些元素,因为erase返回一个指向已擦除元素旁边元素的迭代器。

答案 1 :(得分:1)

问题是您要从正在迭代的向量中删除。从向量中删除对象后,其所有迭代器都将失效;后续访问它们是未定义的行为

要解决此问题,您可以使用索引,并从末尾开始遍历向量。这样,无论是否删除了对象,都可以在每次迭代时递减索引。

答案 2 :(得分:1)

向量元素存储在连续的内存中,因此当您擦除向量的元素时,尾元素(擦除元素之后的元素)必须“移位”,因此向量的所有迭代器都会失效。

答案 3 :(得分:0)

删除所有等于某个值的元素的常用方法是使用标准算法std::remove以及成员函数erase例如

void function()
{
   vector<int> vec1;

    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);

   vec1.erase( std::remove( vec1.begin(), vec1.end(), 4 ), vec1.end() );
}

如果你只想删除一个等于4的元素,你可以写

void function()
{
   vector<int> vec1;

    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);

    auto it = std::find( vec1.begin(), vec1.end(), 4 );

    if ( it != vec1.end() ) vec1.erase( it );
}

如果要使用循环删除所有等于4的元素,则应编写

void function()
{
    vector<int> vec1;

    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);

    for ( auto it = vec1.begin(); it != vec1.end(); )
    {
        if ( *it == 4 ) it = vec1.erase( it );
        else ++it;
    }
}