C++ 删除stl集中的迭代器时出现分段错误

C++ 删除stl集中的迭代器时出现分段错误,c++,stl,iterator,segmentation-fault,set,C++,Stl,Iterator,Segmentation Fault,Set,我有一个程序,它迭代一个集合并替换一个元素,调用它自己,直到它不能继续,然后撤销它所做的并搜索下一个分支 for(set<int>::iterator it=set1.begin();it!=set1.end();) { if(condition) { int l=*it; if(condition) set1.insert(l-rails[inuse]).first; s

我有一个程序,它迭代一个集合并替换一个元素,调用它自己,直到它不能继续,然后撤销它所做的并搜索下一个分支

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;
    }

但我不明白是什么原因造成的。我想这与我如何使用迭代器有关,但我找不到它。可能会出现什么问题?

在迭代时,请注意更改集合-如果其中一个递归调用删除了迭代器
所引用的元素,则该元素将不再有效。考虑到每个递归调用从一开始就迭代整个集合,这是一种可能性。

您想用这些实现什么?至少乍一看,根本不清楚你在做什么,或者为什么要这样做。您已经从树本身(或多或少)的角度解释了您要做什么,但没有解释所有这些都应该完成什么。迭代器n
的目的是什么?它不再被使用。递归调用令人担忧。如果它使
it
无效该怎么办?您正在对一个函数进行递归调用,该函数修改
std::set
,并从
set1.begin()
循环整个集合?如何确保递归调用不会修改当前循环中的某个位置之前的内容,或者(更糟的是)与当前循环中的位置完全相同?如果循环不是以
set1.begin()
开始的,那就不难确保了,但是递归调用可能会遇到您的“危险迭代器”并删除它所引用的内容,这看起来确实很可疑!如果您可以使用相对较新版本的MSVC构建项目,那么调试构建具有迭代器调试功能,它可以很好地告诉您何时使用无效迭代器。
==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)