我正在尝试删除向量的内容而我收到错误 - 向量迭代器不可递增,为什么会这样?
这是我的析构函数:
City::~City()
{
vector <Base*>::iterator deleteIterator;
for (deleteIterator = m_basesVector.begin() ; deleteIterator != m_basesVector.end() ; deleteIterator++)
m_basesVector.erase(deleteIterator);
}
感谢。
答案 0 :(得分:44)
erase
使迭代器无效。你不能再使用它了。幸运的是,它返回一个你可以使用的迭代器:
vector <Base*>::iterator deleteIterator = m_basesVector.begin();
while (deleteIterator != m_basesVector.end()) {
deleteIterator = m_basesVector.erase(deleteIterator);
}
或者:
m_basesVector.clear();
你是否有责任释放向量中指针引用的内存?如果这就是你正在迭代的原因(并且你的真实程序有更多你没有显示的代码,那就是释放循环中的那些对象),那么请记住,从向量的开头擦除是一个缓慢的操作,因为在每一步中,矢量的所有元素都必须向下移动一个位置。更好的是循环向量释放所有东西(然后clear()
向量,尽管迈克说如果向量是被破坏的对象的成员则没有必要。
答案 1 :(得分:11)
问题是您在使用erase()函数时尝试使用迭代器。 erase(),push_back(),insert()和其他修改函数使STL中的迭代器无效。
只需使用clear()函数:
City::~City()
{
m_basesVector.clear();
}
答案 2 :(得分:3)
如果您尝试释放向量中的数据,请执行以下操作:
for (std::vector<Base*>::iterator it = v.begin(), e = b.end(); it != e; ++it)
delete *it;
答案 3 :(得分:2)
发布这个只是因为其他人有这个问题,并尝试这个解决方案,想知道为什么它不能在这里工作是一个实际的解决方案/解释。
@Steve Jessop - 你的代码存在缺陷,你也在这里写了......(我也编辑了他的帖子,一旦它被批准就修复了它,它将在原帖中修复)
http://techsoftcomputing.com/faq/3779252.html
我不知道这是一个问题的“解决方案”,当它通过无限循环创建一个新问题时,while循环中应该有一个deleteIterator ++,以便它实际到达向量的末尾。 / p>
此外我遇到了这个问题,我的解决方案是在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;
}
答案 4 :(得分:2)
这与上面发布的原始问题无关,但Google搜索错误会将我带到此页面,因此我将其发布在此处供所有人查看。
我最近遇到了这条错误消息并检出了所有代码行(没有'擦除'或类似内容;只是读取了矢量)。
最终,我意识到嵌套循环存在问题。
例如,考虑这样的事情:
`for (it=begin(); it!=end();i++)
{
for (; it!=end();i++)
{
}
}`
当你完成嵌套循环时,它将递增迭代器 - 然后,父循环将再次递增它(!),最终使迭代器步骤超过end()。即如果有这样的事情,它将是“结束()+ 1”。 因此,父循环在下次检查时抛出此错误。
为了解决这个问题,我最终在子循环之后插入了这一行:
`if (it == vStringList.end()) --it;`
很脏,但有效:D
我知道这对某些人来说可能是显而易见的,但我一直在摸不着头脑,哈哈尔
答案 5 :(得分:1)
当调用向量的erase方法时,指向已删除元素或删除元素之后的元素的任何迭代器都将失效。 Erase方法返回指向向量中下一个元素的有效迭代器。您应该使用该迭代器继续循环&amp;不增加无效的迭代器。您还可以使用clear方法删除向量中的所有元素。但是,您需要记住明确地为元素重新分配任何已分配的内存。
答案 6 :(得分:1)
此代码泄漏了向量的所有内容 - 您也必须在循环中delete *deleteIterator
。您可以使用Base
代替Base*
作为vector
内容来避免所有这些,然后clear()
将为您销毁它们。或者使用boost::ptr_vector
,如果你需要原始指针,它会自动销毁。
如果erase()
很大,那么在这样的前向迭代中调用vector
可能会非常昂贵,因为当前位置上方的每个元素都必须向下移动以确保元素保持连续。由于这个原因和其他原因,请避免手动删除您建议的类型。
答案 7 :(得分:0)
向量迭代器是可递增的,但是如果删除元素,则会修改向量内容,因此迭代器无效。
因此,如果删除对象,则应使用erase()
的返回值,它将为您提供下一个有效的迭代器。