簡體   English   中英

迭代時從std :: list中刪除

[英]Removing from std::list while iterating

我有以下代碼:

bool resetTypeBit = true;
for (auto it = eventsList.begin(); it != eventsList.end(); ++it) {
    CreatureEvent* curEvent = *it;
    if (curEvent == event) {
        it = eventsList.erase(it);
    } else if (curEvent->getEventType() == type) {
        resetTypeBit = false;
    }
}

所以我有以下情形: eventList包含01項,然后,一旦for語句第一次通過並滿足it = eventsList.erase(it); 行, it變量變為無效,從而在for語句的下一次迭代中導致分段錯誤。

任何可能導致問題的線索?

如果您刪除的項目是列表中的最后一個項目,則erase方法將返回end() 然后,您的for循環將嘗試遞增該迭代器,這將導致未定義的行為。

您還沒有遇到的另一個問題是,如果您刪除的項目不是列表中的最后一個項目,您最終將跳過以下項目(因為迭代器的增量超過了erase返回的那個) )。 您可以將erase視為增量操作,而該操作恰好是先擦除項目。

解決方案是稍微重構循環,將增量移到末尾(並且僅在未調用erase下):

bool resetTypeBit = true;
for (auto it = eventsList.begin(); it != eventsList.end(); ) {
    CreatureEvent* curEvent = *it;
    if (curEvent == event) {
        it = eventsList.erase(it);
    }
    else {
        if (curEvent->getEventType() == type) {
            resetTypeBit = false;
        }
        ++it; // move the increment to here
    }
}

就像現在所寫的那樣,即使在erase分支中,您也要遞增迭代器,這意味着您總是在擦除一個元素之后才跳過該元素。 如果最后一個元素碰巧是要刪除的元素,則這既不正確,又會導致嚴重的問題。 要進行修復,如果已經解決, it不必通過將其設置為已刪除元素之后的元素來增加it

bool resetTypeBit = true;
for (auto it = eventsList.begin(); it != eventsList.end(); ) {
    CreatureEvent* curEvent = *it;
    if (curEvent == event) {
        it = eventsList.erase(it);
        continue;
    } else if (curEvent->getEventType() == type) {
        resetTypeBit = false;
    }
    ++it;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM