C++ 递归函数中带迭代器的Seg故障
我试图用递归函数对向量中的整数进行排序。我的程序运行、编译和排序数据,但事实上,它给了我一个seg错误。我认为这是因为for循环使用了向量中已更改的地址,导致它永远不会离开循环C++ 递归函数中带迭代器的Seg故障,c++,recursion,vector,iterator,segmentation-fault,C++,Recursion,Vector,Iterator,Segmentation Fault,我试图用递归函数对向量中的整数进行排序。我的程序运行、编译和排序数据,但事实上,它给了我一个seg错误。我认为这是因为for循环使用了向量中已更改的地址,导致它永远不会离开循环 void Plays::SortRelevance(vector<Plays> list){ cout << "in the loop" << endl; for(vector<Plays>::iterator i=list.begin(); i != list.end
void Plays::SortRelevance(vector<Plays> list){
cout << "in the loop" << endl;
for(vector<Plays>::iterator i=list.begin(); i != list.end(); ++i){
cout << i->relevance << endl;
}
for(vector<Plays>::iterator i=list.begin(); i != list.end(); ++i){
if(i->relevance < (i+1)->relevance){
cout << "IN THE THINGY WAT" << endl;
Plays temp(*i);
list.erase (i);
list.push_back (temp);
SortRelevance(list);
cout << "left recursive" << endl;
}
cout << "stuck?" << endl;
}
cout << "left the loop" << endl;
for(vector<Plays>::iterator i=list.begin(); i != list.end(); ++i){
cout << i->relevance << endl;
}
提前感谢任何能为我解释这一点的人
编辑:与其说我已经解决了这个问题,不如说我已经找到了一个更好更优雅的方法来解决它。我创建了一个类,重载了运算符,然后使用sort()函数对需要执行的操作进行排序
void Plays::SortRelevance(vector<Plays> list){
这一行使列表的所有迭代器无效(这是一个糟糕的名称——它是一个向量,而不是列表)。这意味着i
无效,因此循环的下一个++i
同样无效
这一行使列表的所有迭代器无效(这是一个糟糕的名称——它是一个向量,而不是列表)。这现在意味着
i
无效,因此循环的下一个++i
同样无效。您不能对无效迭代器进行操作,并且擦除(it)
使it
无效。典型的擦除循环如下所示:
for (auto it = v.cbegin(); it != v.cend() /* not hoisted */; /* no increment */)
{
if (delete_condition)
{
it = v.erase(it); // or "v.erase(it++);"
}
else
{
++it;
}
}
(在C++11的标准库中进行了一些清理,使所有容器擦除函数返回下一个迭代器,但情况并非如此,带有
it++
的版本可能会在更多平台上工作。)您不能在无效迭代器上操作,擦除(it)
使无效。典型的擦除循环如下所示:
for (auto it = v.cbegin(); it != v.cend() /* not hoisted */; /* no increment */)
{
if (delete_condition)
{
it = v.erase(it); // or "v.erase(it++);"
}
else
{
++it;
}
}
(在C++11的标准库中进行了一些清理,以使所有容器擦除函数返回下一个迭代器,但情况并非如此,并且带有it++
的版本可能在更多平台上工作。)影响容器内容的操作会使以前实例化的迭代器失效,因此,在使用迭代器对容器进行转换时,绝对不应修改容器(当然,如果没有更新迭代器,请参见@KerrekSB answer示例:他使用擦除函数返回的迭代器更新迭代器),影响容器内容的操作会使以前实例化的迭代器无效,因此,在使用迭代器对容器进行转换时,您永远不应该修改容器(当然,如果您没有更新迭代器,请参阅@KerrekSB answer,例如:他使用erase函数返回的迭代器更新迭代器),所以您告诉我,实现这一点的方法是将If语句分成两部分?一个执行函数中的所有代码,另一个在不满足删除条件时迭代for循环?还有,你所说的删除条件是什么意思。?你是说这个吗?“if(i->relevance<(i+1)->relevance)”那么你是说把if语句分成两部分?一个执行函数中的所有代码,另一个在不满足删除条件时迭代for循环?还有,你所说的删除条件是什么意思。?你是说这个吗?“如果(i->相关性<(i+1)->相关性)”
list.erase (i);
for (auto it = v.cbegin(); it != v.cend() /* not hoisted */; /* no increment */)
{
if (delete_condition)
{
it = v.erase(it); // or "v.erase(it++);"
}
else
{
++it;
}
}