Код связанного списка C зависает без возврата из функции «освобождения»

#c #linked-list #free #freeze

#c #связанный список #Бесплатно #замораживание

Вопрос:

Для программы, над которой я работаю, у меня есть двусвязный список. Теперь мне нужно определить конкретный узел, где определенные данные (вызываемые id ) становятся отрицательными, а затем разыменовать следующие узлы, а также освободить память. Когда я вызываю эту функцию (вставленную ниже), выполняется последний оператор печати и выводится на экран. Однако программа не возвращается в main. Он просто зависает. (Сразу после вызова этой функции у меня есть еще один оператор печати, который не выполняется, и программа зависает там бесконечно).

 static void clear_ghosts(particles *plist)
{
  particles * temp = plist;

  while(temp!=NULL) {
      if(temp->p->id < 0)
      {
          break;
      }
  temp = temp->next;

 }

 if(temp)
 {
     particles * current = temp;
     particles * next;
     while(current !=NULL)
     {
         next = current->next;
         free(current);
         current = next;
     }
     temp = NULL;
 }

 printf("n Finished Clearing n");
 return;

}
  

Вот plist связанный список типа struct particle * . plist имеет данные p , которые сами по себе являются структурой, и имеет данные-члены, такие как id etc. Мне нужно перебрать список и завершить список, когда встречается отрицательный идентификатор участника. Я получаю вывод «Завершенная очистка», но функция не возвращается в main.

Что может быть не так?

Комментарии:

1. Опубликуйте код в main, похоже, проблема может быть там.

2. Как вы определяете, что он не возвращается в main?

3. Если он действительно двусвязный, вам также следует что-то сделать с prev полями.

4. вы прерываете 1-й цикл while на узле, где id < 0, а затем завершаете список с этого узла, но что касается узла, непосредственно предшествующего этому узлу? вы не устанавливаете предыдущий узел рядом с NULL…in способ, искажающий список.

Ответ №1:

Вы уверены, что все элементы, которые вы пытаетесь free() выделить, были выделены malloc() ? Если, например, некоторые из этих указателей указывают на память в стеке, при попытке к ним могут произойти всевозможные ужасные вещи free() .

Ответ №2:

Поскольку вы говорите, что это двухсвязный список, вы должны установить следующий указатель предыдущего элемента на NULL:

 if (temp)
{
   if ( temp != plist )
   {
     temp->prev->next = NULL;
   }
...