【问题标题】:Why is this vector iterator not incrementable?为什么这个向量迭代器不能递增?
【发布时间】:2011-04-16 07:21:06
【问题描述】:

我正在尝试删除向量的内容,但出现错误 - 向量迭代器不可递增,这是为什么呢?

这是我的析构函数:

City::~City()
{
    vector <Base*>::iterator deleteIterator;
    for (deleteIterator = m_basesVector.begin() ; deleteIterator != m_basesVector.end() ; deleteIterator++)
        m_basesVector.erase(deleteIterator);
}  

谢谢。

【问题讨论】:

  • 假设m_basesVectorCity 的成员,则无需删除其元素;它的析构函数即将为你做这件事。
  • 您知道这不会删除您的指针指向的对象。您必须致电delete deleteIterator; 来实现这一点(如果这是您想要的)。但是,在这种情况下,您应该更喜欢boost::ptr_vector
  • there

标签: c++ memory-management vector iterator


【解决方案1】:

这与上面发布的原始问题无关,但谷歌搜索错误会将我带到此页面,因此我将其发布在此处供任何人查看。

我最近遇到了这个错误消息,并且检查了所有代码行(没有“擦除”或类似的东西;向量只是被读取了)。

最终,我意识到嵌套循环存在问题。

例如,考虑这样的事情:

`for (it=begin(); it!=end();i++)
{
    for (; it!=end();i++)
    {
    }
}`

当您完成嵌套循环后,它将递增迭代器 - 然后,父循环将再次递增它(!),最终使迭代器跨步结束()。 IE。如果有这样的事情,那将是“end()+1”。 因此,父循环在下一次检查时抛出此错误。

为了解决这个问题,我最终在子循环之后插入了这一行:

`if (it == vStringList.end()) --it;`

脏,但可以工作:D

我知道这对某些人来说可能很明显,但我已经为此摸不着头脑了一段时间,哈哈

【讨论】:

    【解决方案2】:

    发布此内容以防其他人遇到此问题并尝试此解决方案,想知道为什么它不起作用这里是一个实际的解决方案/解释。

    @Steve Jessop - 你的代码有缺陷,你也把它写在这里......(我还编辑了他的帖子以解决问题,一旦它被批准,它将在原始帖子中修复)

    http://techsoftcomputing.com/faq/3779252.html

    当它通过无限循环创建新问题时,我看不出这是一个“解决方案”,在 while 循环中应该有一个 deleteIterator++,以便它实际上到达向量的末尾。

    我也遇到过这个问题,我的解决方案是在 while 循环中检查迭代器是否等于结尾,或者向量大小是否为 0 并在尝试递增迭代器之前中断。

    例如

        std::vector<RankPlayer*>::iterator Rank_IT = CurrentPlayers.begin();
    
        while ( Rank_IT != CurrentPlayers.end() ) 
        {    
            RankPlayer* SelPlayer = (*Rank_IT);
    
            if( strstr( SelPlayer->GamerTag, this->GamerTag ) != NULL )
            {
    
                delete[] SelPlayer->PlayerData;
                delete[] SelPlayer;
                Rank_IT = CurrentPlayers.erase( Rank_IT );
            }
    
            if( Rank_IT == CurrentPlayers.end() || CurrentPlayers.size() == 0 )
            {
                break;
            }
                ++Rank_IT;
        }
    

    【讨论】:

    • 这是一个答案和一个咆哮,也是一个评论。我强烈建议减少它的咆哮和评论,否则它会很快被删除。
    【解决方案3】:

    这段代码泄露了向量的所有内容——你也必须在循环中delete *deleteIterator。您可以通过使用Base 而不是Base* 作为vector 的内容来避免所有这些,然后clear() 将为您销毁它们。如果您确实需要原始指针,或者使用 boost::ptr_vector 自动销毁。

    如果vector 很大,在这样的前向迭代中调用erase() 可能会非常昂贵,因为当前位置上方的每个元素都必须向下移动以确保元素保持连续。由于这个原因和其他原因,请避免手动擦除您建议的类型。

    【讨论】:

      【解决方案4】:

      erase 使迭代器无效。你不能再使用它了。幸运的是,它返回了一个可以使用的迭代器:

      vector <Base*>::iterator deleteIterator = m_basesVector.begin();
      while (deleteIterator != m_basesVector.end()) {
          deleteIterator = m_basesVector.erase(deleteIterator);
      }
      

      或者:

      m_basesVector.clear();
      

      您是否负责释放向量中指针所指的内存?如果这是您进行迭代的原因(并且您的真实程序有更多未显示的代码,这会释放循环中的这些对象),那么请记住,从向量的开头擦除是一个缓慢的操作,因为在每一步,向量的所有元素都必须向下移动一个位置。更好的是循环释放所有内容的向量(然后clear() 向量,尽管正如 Mike 所说,如果向量是被销毁对象的成员,则没有必要这样做)。

      【讨论】:

        【解决方案5】:

        如果您尝试释放向量中的数据,请执行以下操作:

        for (std::vector<Base*>::iterator it = v.begin(), e = b.end(); it != e; ++it) 
            delete *it;
        

        【讨论】:

          【解决方案6】:

          当调用向量的擦除方法时,任何指向被删除元素或被删除元素之后的元素的迭代器都会失效。 Erase 方法返回一个有效的迭代器,指向向量中的下一个元素。您应该使用该迭代器来继续循环,而不是增加无效的迭代器。您也可以使用 clear 方法删除向量中的所有元素。但是,您需要记住显式取消为元素分配的所有内存。

          【讨论】:

            【解决方案7】:

            向量迭代器是可递增的,但如果删除元素,向量内容会被修改,因此迭代器无效。

            所以,如果你删除对象,你应该使用erase()的返回值,它会为你提供下一个有效的迭代器。

            【讨论】:

              【解决方案8】:

              问题是您在使用 erase() 函数时尝试使用迭代器。 erase()、push_back()、insert() 和其他修改函数使 STL 中的迭代器无效。

              只需使用 clear() 函数:

              City::~City()
              {
                  m_basesVector.clear();
              }  
              

              【讨论】:

              • 嗯,它们是否使迭代器无效取决于容器类型。
              • @Matt,使用向量时不依赖。
              • @Matt: erase 将始终使引用已擦除元素的迭代器无效。
              • 另一个潜在的问题是,如果有必要,使用 clear() 不会在将指针从向量中删除之前删除它们。
              • @Matt:erase() 也不会。
              猜你喜欢
              • 2014-05-17
              • 1970-01-01
              • 2021-03-10
              • 1970-01-01
              • 1970-01-01
              • 2019-10-27
              • 2011-02-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多