C++ 为什么这个向量迭代器不可递增?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3779227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is this vector iterator not incrementable?
提问by Roy Gavrielov
I'm trying to delete the vector's content and I'm getting an error - vector iterator is not incrementable, why is that?
我正在尝试删除向量的内容,但出现错误 - 向量迭代器不可递增,这是为什么?
This is my destructor:
这是我的析构函数:
City::~City()
{
vector <Base*>::iterator deleteIterator;
for (deleteIterator = m_basesVector.begin() ; deleteIterator != m_basesVector.end() ; deleteIterator++)
m_basesVector.erase(deleteIterator);
}
thanks.
谢谢。
回答by Steve Jessop
erase
invalidates the iterator. You can't use it any more. Luckily for you, it returns an iterator that you can use:
erase
使迭代器无效。你不能再使用它了。幸运的是,它返回一个可以使用的迭代器:
vector <Base*>::iterator deleteIterator = m_basesVector.begin();
while (deleteIterator != m_basesVector.end()) {
deleteIterator = m_basesVector.erase(deleteIterator);
}
Or:
或者:
m_basesVector.clear();
Are you responsible for freeing the memory referred to by the pointers in the vector? If that's the reason that you're iterating (and your real program has more code that you haven't shown, that frees those objects in the loop), then bear in mind that erasing from the beginning of a vector is a slow operation, because at each step, all the elements of the vector have to be shifted down one place. Better would be to loop over the vector freeing everything (then clear()
the vector, although as Mike says that's not necessary if the vector is a member of an object that's being destroyed).
你负责释放向量中的指针所指的内存吗?如果这就是您迭代的原因(并且您的实际程序有更多您没有显示的代码,这会释放循环中的那些对象),那么请记住,从向量的开头擦除是一个缓慢的操作,因为在每一步,向量的所有元素都必须向下移动一个位置。更好的是循环遍历向量以释放所有内容(然后clear()
是向量,尽管正如 Mike 所说,如果向量是被销毁对象的成员,则没有必要)。
回答by riwalk
The problem is that you are trying to use an iterator while using the erase() function. erase(), push_back(), insert(), and other modifying functions invalidate iterators in STL.
问题是您在使用 erase() 函数时尝试使用迭代器。erase()、push_back()、insert() 和其他修改函数使 STL 中的迭代器无效。
Just use the clear() function:
只需使用 clear() 函数:
City::~City()
{
m_basesVector.clear();
}
回答by jmucchiello
If you are trying to free the data in the vector, do this:
如果您尝试释放向量中的数据,请执行以下操作:
for (std::vector<Base*>::iterator it = v.begin(), e = b.end(); it != e; ++it)
delete *it;
回答by Tim Lawrence
Posting this just incase anyone else has this this problem and attempts this solution wondering why it's not working here's an actual solution/explanation.
发布这个只是为了防止其他人遇到这个问题并尝试这个解决方案想知道为什么它在这里不起作用是一个实际的解决方案/解释。
@Steve Jessop - Your code is flawed and you've also got it written here... ( I've also edited his post to fix the issue as soon as it's approved it'll be fixed in the original post )
@Steve Jessop - 你的代码有缺陷,你也把它写在这里......(我还编辑了他的帖子以在它获得批准后立即修复该问题,它将在原始帖子中修复)
http://techsoftcomputing.com/faq/3779252.html
http://techsoftcomputing.com/faq/3779252.html
I don't see how this is a "Solution" to the issue when it create an new issue by making an endless loop there should be a deleteIterator++ within the while loop so that it actually reaches the end of the vector.
当它通过无限循环创建新问题时,我不明白这是如何解决问题的,while 循环中应该有一个 deleteIterator++,以便它实际上到达向量的末尾。
Also I've ran into this problem and my solution was inside the while loop checking whether the iterator was equal to the end or if the vector size was 0 and breaking before attempting to incrementing the iterator.
我也遇到了这个问题,我的解决方案是在 while 循环中检查迭代器是否等于结束或者向量大小是否为 0 并在尝试增加迭代器之前中断。
Ex.
前任。
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;
}
回答by Csimbi
This is not relevant to the original problem posted above, but Google search on the error takes me to this page so I am posting it here for anyone to see.
这与上面发布的原始问题无关,但 Google 对错误的搜索会将我带到此页面,因此我将其发布在这里供任何人查看。
I ran into this error message recently and all lines of codes checked out (there was no 'erase' or anything alike; the vector was merely read).
我最近遇到了这个错误消息,并且检查了所有代码行(没有“擦除”或类似的东西;只是读取了向量)。
Eventually, I realized that there is a problem with nested loops.
最终,我意识到嵌套循环存在问题。
For example, consider something like this:
例如,考虑这样的事情:
`for (it=begin(); it!=end();i++)
{
for (; it!=end();i++)
{
}
}`
When you are done with the nested loop, it will increment the iterator - and then, the parent loop will increment it again(!), ultimately making the iterator step over the end(). I.e. it would be "end()+1" if there were such a thing. Consequently, the parent loop throws this error at the next check.
当您完成嵌套循环时,它将增加迭代器 - 然后,父循环将再次增加它(!),最终使迭代器跳过 end()。即如果有这样的事情,它将是“end()+1”。因此,父循环在下一次检查时抛出此错误。
To get around this, I ended up insert this line after the child loop:
为了解决这个问题,我最终在子循环之后插入了这一行:
`if (it == vStringList.end()) --it;`
Dirty, but works :D
脏,但有效:D
I know it may be obvious to some, but I've been scratching my head over this for a while, lol
我知道这对某些人来说可能很明显,但我已经为此挠头一段时间了,哈哈
回答by Steve Townsend
This code leaks all the contents of the vector - you have to delete *deleteIterator
in the loop too. You can avoid all of this by using Base
instead of Base*
as the vector
contents, then clear()
will destruct them for you. Or use boost::ptr_vector
which automates destruction if you do need raw pointers.
这段代码泄漏了向量的所有内容——你也必须delete *deleteIterator
在循环中。您可以通过使用Base
而不是Base*
作为vector
内容来避免所有这些,然后clear()
将为您销毁它们。或者boost::ptr_vector
,如果您确实需要原始指针,请使用which 自动销毁。
Calling erase()
in a forward iteration like this can be very costly if the vector
is large, as every element above the current position has to be moved down to ensure elements remain contiguous. Avoid manual erase of the type you propose, for this and other reasons.
erase()
如果vector
很大,调用这样的前向迭代可能会非常昂贵,因为当前位置上方的每个元素都必须向下移动以确保元素保持连续。出于这个原因和其他原因,避免手动擦除您建议的类型。
回答by naivnomore
Any iterator pointing to the deleted element or to the elements after the one that is deleted gets invalidated when the vector's erase method is called. Erase method returns a valid iterator pointing to the next element in the vector. You should use that iterator to continue your looping & not increment the invalidated iterator. You may also use the clear method to remove all the elements in the vector. However, you will need to remember to explicitly de-allocate any allocated memory for the elements.
当向量的擦除方法被调用时,任何指向被删除元素或被删除元素之后的元素的迭代器都会失效。Erase 方法返回一个指向向量中下一个元素的有效迭代器。您应该使用该迭代器来继续循环,而不是增加无效的迭代器。您也可以使用 clear 方法删除向量中的所有元素。但是,您需要记住为元素显式取消分配任何已分配的内存。
回答by msteiger
Vector iterators are incrementable, but if you delete elements, the vector contents are modified and thus the iterator is invalid.
向量迭代器是可递增的,但如果删除元素,则向量内容被修改,因此迭代器无效。
So, if you delete objects, you should use the return value of erase()
that gives you the next valid iterator.
所以,如果你删除对象,你应该使用它的返回值erase()
给你下一个有效的迭代器。