2013-09-16 4 views
1

Я пытаюсь сортировать целые числа в векторе, используя рекурсивную функцию. Моя программа запускает, компилирует и сортирует данные, но после того, как она дает мне ошибку seg. Я думаю, что это из-за цикла for, используя адреса в векторе, которые были изменены, заставляя его никогда не покидать цикл.Ошибка Seg с итераторами в рекурсивной функции

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

}

Конец моей продукции выглядит следующим образом, отсортированные но дает сбой сегм в конце:

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 

Спасибо заранее всем, кто может пролить некоторый свет на этот для меня.

EDIT: У меня не так много исправлено проблема, поскольку я нашел лучший и элегантный способ сделать это. Я создал класс, перегрузил операторы, а затем использовал функцию sort() для сортировки того, что мне нужно было сделать.

+0

Операции, влияющие на содержимое контейнера, недействительны ранее инициализированные итераторы, поэтому ** вы никогда не должны изменять контейнер, пока вы перебираете его с помощью итераторов ** (Если вы не обновили итераторы, конечно. См. Например, ответ @KerrekSB: он обновляет итератор, используя итератор, возвращаемый функцией стирания) – Manu343726

ответ

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, чтобы все функции контейнеров стирают возвращают следующий итератор, но не использовать и версия с it++ может работать на большем количестве платформ.)

+0

Итак, вы говорите мне, что путь это разбить мое заявление if на две части? Тот, который выполняет весь мой код в функции, а другой, который выполняет итерацию цикла for, если условие удаления не выполняется? А также, что вы имели в виду по условию удаления.? Вы имеете в виду это? "\t если (i-> релевантность < (i+1)-> релевантность)" – TheOneTrueSign

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

Эта подпись принимает копию списка каждый раз. Вероятно, вы хотите, чтобы это была ссылка.

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

Когда i является последним элементом (т.е. i+1==list.end()), это выходит за пределы.

list.erase (i); 

Эта линия аннулирует все итераторы для списка (который является страшным именем - это вектор, а не список). Это означает, что i недействителен, поэтому следующий ++i цикла недействителен.

Смежные вопросы