繁体   English   中英

为什么这个向量迭代器不可递增?

[英]Why is this vector iterator not incrementable?

我正在尝试删除向量的内容而我收到错误 - 向量迭代器不可递增,为什么会这样?

这是我的析构函数:

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

谢谢。

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

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

要么:

m_basesVector.clear();

你负责释放向量中指针引用的内存吗? 如果这就是你正在迭代的原因(并且你的真实程序有更多你没有显示的代码,那就是释放循环中的那些对象),那么请记住,从向量的开头擦除是一个缓慢的操作,因为在每一步中,矢量的所有元素都必须向下移动一个位置。 更好的是循环向量释放所有东西(然后clear()向量,尽管迈克说如果向量是被破坏的对象的成员则没有必要)。

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

只需使用clear()函数:

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

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

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

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

我最近遇到了这个错误消息并检出了所有代码行(没有'擦除'或类似的东西;仅仅读取了向量)。

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

例如,考虑这样的事情:

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

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

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

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

很脏,但有效:D

我知道这对某些人来说可能是显而易见的,但我一直在摸不着头脑,哈哈哈

发布这个只是因为其他任何人都有这个问题,并尝试这个解决方案,想知道为什么它不起作用这里是一个实际的解决方案/解释。

@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;
    }

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

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

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

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

因此,如果删除对象,则应使用erase()的返回值,该值为您提供下一个有效的迭代器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM