#c #linked-list #segmentation-fault #doubly-linked-list
#c #связанный список #ошибка сегментации #дважды связанный список
Вопрос:
struct someEvent
{
int id;
int shouldRemove;
struct someEvent *prev;
struct someEvent *next;
} * someEvent;
struct someEvent *someEventQueue = NULL;
int main(){
struct someEvent **curr5 = amp;someEventQueue;
while ((*curr5) != NULL)
{
if ((*curr5)->shouldRemove == 1)
{
tmpflag = 1;
if ((*curr5)->prev == NULL amp;amp; (*curr5)->next == NULL)
{
(*curr5) = NULL;
}
else if ((*curr5)->prev == NULL)
{
(*curr5) = (*curr5)->next;
(*curr5)->prev = NULL;
//(*curr5)->prev->next = (*curr5)->next;
}
else if ((*curr5)->next == NULL)
{
(*curr5)->prev->next = NULL;
}
else
{
(*curr5)->prev->next = (*curr5)->next;
(*curr5)->next->prev = (*curr5)->prev;
}
}
if (tmpflag == 1)
{
break;
}
curr5 = amp;(*curr5)->next;
}
}
Я сделал свой код таким. Я хочу удалить узел, который должен быть перемещен равным 1.
Эта картинка — someEventQueue . Я хочу удалить узел, идентификатор которого равен 2.
Я хочу этот результат. Но в моем результате есть некоторые ошибки…
Эта картинка является результатом моего кода. После отладки я обнаружил, почему у него ошибка. (*curr5)->prev->next = (*curr5)->next;
эта часть отлично работает. Но после того, как эта часть (*curr5)
будет изменена на (*curr5)->next
и (*curr5)->next->prev = (*curr5)->prev;
этот код вернет ошибку сегментации. Я не знаю, почему произошло такое изменение. Для решения этой проблемы я добавляю (*curr5)=(*curr5)->prev;
между (*curr5)->prev->next = (*curr5)->next;
и (*curr5)->next->prev = (*curr5)->prev;
. Затем это завершается бесконечным циклом… Я думаю, что в моем коде нет ошибок, но я не знаю, почему (* curr5) изменяется после (*curr5)->prev->next = (*curr5)->next;
. Мне нужен совет.
Комментарии:
1. Не связано, вы намеревались, чтобы этот код объявлял глобальную переменную
someEvent
типаstruct someEvent *
? Если нет (т. Е. Если Вы вырезали typedef при вставке этого в SO), то прекратите скрывать указатели в typedef; это почти всегда плохая идея.
Ответ №1:
Вы делаете это более сложным, чем нужно. Похоже, что код хочет удалить первый узел в списке, для которого установлен shouldRemove
флаг, а затем остановить. Управление узлами в двойных списках связано с двумя вещами:
- указатель, который приведет вас туда.
- узел, если таковой имеется, который содержит этот указатель.
Т.е.
int main()
{
struct someEvent **curr = amp;someEventQueue;
struct someEvent *prev = NULL;
while (*curr)
{
if ((*curr)->shouldRemove)
{
struct someEvent *tmp = *curr;
*curr = tmp->next;
if (tmp->next)
tmp->next->prev = prev;
// added to prevent memory leak. remove if these are
// maintained somewhere else.
free(tmp);
break;
}
else
{
prev = *curr;
curr = amp;(*curr)->next;
}
}
}
Стоит отметить, что вы можете удалить все узлы с shouldRemove
установленным флагом, удалив break;
в приведенном выше цикле.