簡體   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