[英]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.