首页 文章

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

提问于
浏览
0

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

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 回答

  • 1

    erase 方法将使迭代器无效 . 你必须写:

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

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

  • 4

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

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

  • 0

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

  • 1

    删除所有等于某个值的元素的常用方法是使用标准算法 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;
        }
    }
    

相关问题