2016-08-16 19 views
1

以下のコードを実行すると、テスト1の4番目の値(1と3の値と同じではありません)に異なるアドレスが表示されます。これは、rend()がrbegin()と同じであることを示しています。 私はループが2回目の繰り返しを経てsegfaultを取得することも期待しません。C++のrend()はrbegin()と同じ要素を指します

私が間違っていることは何ですか?

map<unsigned long, int*> newMap; 
newMap[13] = new int(1340); 
cout << "test 1:" << endl; 
cout << &(*(newMap.begin())) << endl; 
cout << &(*(newMap.end())) << endl; 
cout << &(*(newMap.rbegin())) << endl; 
cout << &(*(newMap.rend())) << endl; 
cout << "test 2:" << endl; 
for(map<unsigned long, int*>::reverse_iterator it=newMap.rbegin();it!=newMap.rend();){ 
    cout << "next iteration" << endl; 
    map<unsigned long, int*>::reverse_iterator entry = it; 
    it++; 
    delete entry->second; 
    newMap.erase(entry->first); 
} 

出力:

test 1: 
0x2299050 
0x7fffcd574908 
0x2299050 
0x2299050 
test 2: 
next iteration 
next iteration 
*** glibc detected *** ./foo: double free or corruption (fasttop): 0x0000000002299030 *** 

編集:ここでは、更新/簡易版はまだ同じ問題(のみテスト2)で、です。これは、ポインタを使用していないので、セグメンテーション違反を引き起こすが、それでも二回のループを通過しない:テスト1では

map<int, int> newMap; 
newMap[13] = 1340; 
cout << "test 2:" << endl; 
for(map<int, int>::reverse_iterator it=newMap.rbegin();it!=newMap.rend();){ 
    cout << "next iteration" << endl; 
    int index = it->first; 
    int value = it->second; 
    it++; 
    newMap.erase(index); 
} 
+5

'end()'または 'rend()'の参照は、* past-the-end *イテレータを表すのでUBです。 – ArchbishopOfBanterbury

+0

BTW 'newMap [13] =新しいint(1340);'あなたは本当ですか? –

+0

これはテスト1について説明しますが、テスト2についてはどうですか?最後に簡略化した例を追加しました。 – 3pitom3

答えて

0

は、あなたが過去・エンドのイテレータを参照外しされています。コメントでArchbishopOfBanterburyが述べたように、この結果は未定義です。

テスト2では、it.base()が指す要素を消去してitを無効にしています。 std::reverse_iteratorは、次の要素にイテレータを保持します(newMap.rbegin()newMap.end()に等しいイテレータを保持し、newMap.rend()newMap.begin()に等しいイテレータを保持します)。

itを増やすと、newMap.rend()に等しくなり、it.base()newMap.begin()に等しいことを意味します。 it.base()で参照される要素を消去すると、it.base()が無効になり、itも無効になります。 itが現在無効であるため、newMap.rend()と比較すると機能しません。

関連する問題