2

cppは初めてです。イテレータをインクリメントせずに消去するように呼び出すと、プログラムは兆候やクラッシュなしにすぐに終了します。次の例では、「Afterif条件」のみが出力されます。エラーは表示されません。ただし、list.erase(it ++);を正しく呼び出した場合。すべてを印刷するよりも。 私の質問は、私がそれを正しく呼んでいないときに何が起こったのかについてです。クラッシュや終了が表示されないのはなぜですか?私が心配して質問した理由は、この種のクラッシュをキャッチすることについてですが、なぜキャッチブロックでキャッチしなかったのですか?それを捕まえる方法はありますか?

int main(int argc, char *argv[]) {
    try {
        list<int>::iterator it;
        list<int> list;
        list.push_back(1);
        for (it = list.begin(); it != list.end(); ++it) {
            if ((*it) == 1) {
                list.erase(it);
            }
            cerr << "After if condition " << endl;
        }
        cerr << "After for condition" << endl;
    } catch (...) {
        cerr << "catch exception" << endl;
    }
    cerr << "Finish" << endl;
}
4

4 に答える 4

6

差出人std::list::erase()

消去された要素への参照とイテレータは無効になります。

itは消去され++it、未定義の動作を引き起こすことによって使用されます。つまり、何かが発生する可能性があります。

erase()最後に削除された要素に続くイテレータを返します。つまり、の戻り値を格納してerase()続行できますが、実行後に要素をスキップしないようにループを変更する必要がありますerase()

于 2012-07-25T12:32:21.053 に答える
2

イテレータを使用する場合、コンテナを変更することはできません。eraseイテレータをすぐに無効にします。

あなたができることは次のようなものです:

for( list<int>::iterator it = list.begin(); it != list.end();)
  if( (*it) == 1 )        
    it=list.erase(it);
  else
    ++it;

STLリストからアイテムを消去します)

また

for( list<int>::iterator it = list.begin(); it != list.end();)
  if( (*it) == 1 )        
    list.erase(it++);
  else
    ++it;

それについてはたくさんの投稿があります。「消去リストイテレータ」を検索してください!

編集:それ以外の場合、つまりイテレータを無効にし、後で増やす場合、動作は定義されていません。つまり、システムごと、コンパイラごと、実行ごとに異なる可能性があります。

それがクラッシュせず、適切な動作を提供する場合、あなたは幸運です。クラッシュせずに何か他のことをする場合は、見つけるのが難しいバグなので、運が悪いです。

于 2012-07-25T12:28:31.637 に答える
2

it一度消去すると使用できなくなります。++ itを呼び出すと、クラッシュが発生します。要素を消去する前に、次のイテレータを保存します。

于 2012-07-25T12:29:30.420 に答える
0

秘訣はを使用することerase(it++)です。

于 2012-07-25T12:29:20.053 に答える