迭代时从std :: list中删除

Ale*_*ino 2 c++ stl list c++11

我有以下代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我有以下场景:eventList包含01项,然后,一旦for语句第一次通过并遇到该it = eventsList.erase(it);行,it变量就变为无效,导致for语句的下一次迭代出现分段错误.

什么可能导致问题的线索?

Jon*_*ter 5

如果您删除的项目是列表中的最后一项,则该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
    }
}
Run Code Online (Sandbox Code Playgroud)