0

我正在为我的链表实现使用 STL 列表,但是当我在循环中使用擦除函数时,它会给出分段错误。有人能告诉我为什么会这样吗?

void remove(list<int> &myList,int N){
    int k = 1;
    list<int>::iterator it;
    for(it = myList.begin(); it != myList.end();it++){
        if(k == N){
            myList.erase(it);
            k = 1;
        }
        else
            k++;
    }
}
4

3 回答 3

6

当您在迭代器上调用擦除时,它会使该迭代器无效。但是你继续使用它。您需要捕获擦除的返回值,并将其分配回您的迭代器,如下所示:

it = myList.erase(it);

但这将需要对您的循环进行轻微更改。如果你擦除,那么你不想增加,因为你会跳过一个元素。如果您最终擦除了最后一个元素,这尤其糟糕,因为那样您将越过 end 迭代器。所以,如果你不擦除,你应该只增加:

for(it = myList.begin(); it != myList.end(); ){
    if(k == N){
        it = myList.erase(it);
        k = 1;
    }
    else
    {
        k++;
        ++it;
    }
}
于 2012-10-23T01:31:45.860 回答
2

如果你擦除一个元素,它的迭代器就会失效。换句话说,当您进行下一次迭代时,您所做it++的将不再有意义,因为it不再指向列表的元素。

于 2012-10-23T01:31:54.837 回答
1

像这样做,

void remove(list<int> &myList,int N){
    int k = 1;
    list<int>::iterator it;
    for(it = myList.begin(); it != myList.end();){
        if(k == N){
            myList.erase(it++);
            k = 1;
        } else{
            ++it;
            k++;
        }
    }
}

执行代码 myList.erase(it++) 时,迭代器“it”表示的对象无效。因此,未定义执行“it++”

于 2012-10-23T01:37:21.490 回答