在递归函数中使用迭代器进行段错误

时间:2013-09-16 22:07:08

标签: 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(); ++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;
}

}

我的输出结束如下,排序但最后给出一个seg错误:

    IN THE THINGY WAT
in the loop
-62
-62
-62
-69
-71
-72
-80
-81
-87
-89
-94
-100
-104
-107
-107
-112
-137
-142
-145
-150
-151
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
stuck?
Segmentation fault

提前感谢任何可以为我阐明这一点的人。

编辑:我没有解决这个问题,因为我找到了一个更好,更优雅的方法。我创建了一个类,重载了运算符,然后使用sort()函数对我需要做的事情进行排序。

2 个答案:

答案 0 :(得分:4)

您不能对无效的迭代器进行操作,erase(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中的标准库中已经进行了一些清理,以使所有容器擦除函数返回下一个迭代器,但是并不是这样,并且版本为{{1可以在更多平台上工作。)

答案 1 :(得分:1)

void Plays::SortRelevance(vector<Plays> list){

此签名每次都会获取列表的副本。您可能希望将其作为参考。

if(i->relevance < (i+1)->relevance){

i是最后一个元素(即i+1==list.end())时,这超出范围。

list.erase (i);

这一行使列表的所有迭代器无效(这是一个可怕的名称 - 它是一个向量,而不是一个列表)。现在这意味着i无效,因此循环的下一个++i同样无效。