セットを反復処理して要素を置き換え、それ以上進むことができなくなるまで自分自身を呼び出してから、実行したことを元に戻して次のブランチを検索するプログラムがあります。
for(set<int>::iterator it=set1.begin();it!=set1.end();)
{
if(condition)
{
int l=*it;
if(condition) set1.insert(l-rails[inuse]).first;
set<int>::iterator it1=it;
it++;
set1.erase(it1);//this line has the problem
//do other things, including a recursive call
if(l>rails[inuse+1]+rails[inuse]) set1.erase(l-rails[inuse]);
set1.insert(l);
}
else ++it;
}
私のプログラムは正常に動作しているように見え、私のシステムでは正しく動作しますが、別のシステムでセグメンテーション違反が発生してクラッシュします。valgrind
セグメンテーション違反を検出します:
==3610== Process terminating with default action of signal 11 (SIGSEGV)
==3610== Access not within mapped region at address 0x18
==3610== at 0x4EA8039: std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) (in /usr/lib/libstdc++.so.6.0.17)
==3610== by 0x402018: std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_erase_aux(std::_Rb_tree_const_iterator<int>) (stl_tree.h:1497)
==3610== by 0x401A4A: std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::erase(std::_Rb_tree_const_iterator<int>) (stl_tree.h:787)
==3610== by 0x401586: std::set<int, std::less<int>, std::allocator<int> >::erase(std::_Rb_tree_const_iterator<int>) (stl_set.h:517)
==3610== by 0x40104A: test() (fence8.cpp:32)
==3610== by 0x40105E: test() (fence8.cpp:34)
==3610== by 0x40105E: test() (fence8.cpp:34)
==3610== by 0x40105E: test() (fence8.cpp:34)
==3610== by 0x40105E: test() (fence8.cpp:34)
==3610== by 0x40105E: test() (fence8.cpp:34)
==3610== by 0x40105E: test() (fence8.cpp:34)
==3610== by 0x40105E: test() (fence8.cpp:34)
しかし、私はこれを引き起こしているものを理解することはできません。イテレータの使い方と関係があると思いますが、見つかりません。何がうまくいかないのでしょうか?