【问题标题】:cppcheck error : Dangerous iterator usagecppcheck 错误:危险的迭代器使用
【发布时间】:2011-03-14 06:16:09
【问题描述】:

代码:

for(x=abc.begin();x!=abc.end();x++)  
{  
   if(-----)  
   {
      ----  
      abc.erase(x);  
   }
}

错误是:::
危险的迭代器用法
擦除后迭代器无效,因此取消引用或将其与另一个迭代器进行比较是无效的。

上述代码中使用擦除功能有什么错误?

【问题讨论】:

    标签: c++ erase libstdc++


    【解决方案1】:

    从 abc 中删除对应的值后,iterator x 无效。这应该可以解决它:

    x = abc.begin();
    
    while(x != abc.end())
    {
        if (-----)
        {
            ----
            x = abc.erase(x);
            // skipped only to next item
        }
        else
        {   // skip only to next item
            ++x;
        }
    }
    

    STL 容器的erase 模板函数返回下一个元素,即end()

    编辑:感谢 templatetypedef 的评论。

    【讨论】:

    • 这正确地避免了失效,但要小心......你最终会跳过 x 迭代器在那些被删除的元素之后。
    【解决方案2】:

    您在循环中使用 x 作为控制变量。由于它被 erase() 无效,因此您无法确定随后在循环顶部递增它是否安全(或有意义)。

    【讨论】:

      【解决方案3】:

      x 是指向abc 的指针。删除x 指向的项目后,x 应该指向什么以及x++ 应该如何工作?

      【讨论】:

        【解决方案4】:

        您对正在迭代的容器只字未提。容器的类型取决于哪些迭代器无效。确保擦除元素的迭代器无效,但例如在std::vector all 中,过去擦除元素的迭代器将无效(包括end())。并且由于未知原因,尽管set::erase 仅使擦除元素的迭代器无效,但它不会将迭代器返回到下一个元素。

        所以std::set:

        while (x != abc.end()) // end() will not change and even can be stored
        {
            if (...)
                abc.erase(x++); // increments before erasing
            else
                ++x;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-17
          相关资源
          最近更新 更多