2016-04-08 12 views
2

リストlist<x> barとイテレータの配列list<x>::iterator foo[100]はすべての要素をbar.end()で初期化しました。C++イテレータの比較アサーション失敗

私はbarに要素を消去し、挿入し、押し戻すつもりで、barのいくつかの要素にポインタfooを格納したいと思います。私はfoo中の位置が空であるかどうかをチェックする必要があり要素の挿入の場合:

if (foo[my_number] != bar.end()) 
    //do something 1 
else 
    //do something 2 

私はfoo[my_number]はすでにbar要素を指している場合にのみエラーが発生します。 ifは、私はこのエラー(falseの場合、問題はない)だ真である:

Debug Assertion Failed! 

Program: C:\Windows\system32\MSVCP120D.dll 
File: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\list 
Line: 289 

Expression: list iterators incompatible 

を私は挿入後bar.end()は以前と同じではないことhereをお読みください。しかし、要素をプッシュバックしてbar.endfoo[k] = endを比較すると、私のコードは失敗しません。しかし、bar.endfoo[k] = bar.begin() + p(これはbar要素が存在します)との比較に失敗します。

私には何が欠けていますか?どうすればこの問題を解決できますか?私は要素を挿入した後にfooを再現すべきですか?

+3

無効にされたイテレータにアクセスしようとしているようです。あなたは[mcve]を見せてもらえますか? – NathanOliver

+5

反復処理にはイテレータを使用する必要があります。ポインタはイテレータとして扱うことができるようにシンタックスを持っています。イテレータをポインタとして使用することは、通常、悪い考えです。 – molbdnilo

+1

イテレータが指している要素を消去した場合、イテレータが無効になっている可能性があります。 – Rob

答えて

2

insertまたはpush_backの操作では、std::listはイテレータまたは参照を無効にしません。 eraseは、消去された要素に対するイテレータ(および参照)を無効にします。この問題は、イレーザを使用して要素を消去した後、消去後(またはその前)に、この要素イテレータを配列内で更新する必要があります。これはendイテレータよりも優先されます。

問題はまず見つけなければならないということです。消去する前に検索する必要があります。配列とリストを同期させ続ける計画はありますか?以下は

は、あなたがして行うべきではありませんができるか、いくつかの例です:std::listから要素を消去

std::list<int> lst; 
    std::vector<std::list<int>::iterator> arr; 

    // Init arr with end() iterator 
    arr.push_back(lst.end()); 

    // Add new list element 
    lst.push_back(0); 

    // Remember where it is in arr 
    arr[0] = lst.begin(); 

    // Compare it. 
    if (arr[0] == lst.begin()) 
    { 
    std::cout << "this is OK!\n"; 
    } 

    lst.push_back(0); 

    if (arr[0] == lst.begin()) 
    { 
    std::cout << "this is still OK!\n"; 
    } 

    lst.erase(lst.begin()); 
    //arr[0] = lst.end(); - without this, "list iterators incompatible" is issued by VS below 
    if (arr[0] == lst.begin()) 
    { 
    // list iterators incompatible 
    std::cout << "This is WRONG!\n"; 
    } 
2

は(hereを参照)、それを指すイテレータを無効にします。したがって、barから消去する場合は、必ず対応するイテレータをfooから削除してください。その他のすべての操作は、既存のイテレータを有効に保つことになっています。

あなたが見つけたリンクは、反復子の無効化に関して異なる動作をするstd::vectorに関する質問を示しています。

関連する問題