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

イテレータで erase を呼び出すと、そのイテレータが無効になります。しかし、あなたはそれを使い続けます。次のように、erase の戻り値を取得し、それをイテレータに割り当てる必要があります。

it = myList.erase(it);

ただし、これにはループのわずかな変更が必要になります。消去する場合は、1 つの要素をスキップすることになるため、インクリメントしたくありません。最後の要素を消去してしまうと、最後のイテレータを通過することになるため、これは特に悪いことです。したがって、消去しない場合にのみインクリメントする必要があります。

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 に答える