2015-02-14 3 views
2

Я написал простой связанный список в C, проблема возникает, когда я пытаюсь удалить первый узел списка, только первый узел, каждый другой узел может быть удален без каких-либо проблемы. Вот мой код:Удалить функцию рандомизирует значения связанного списка

struct LinkedList * search_ret_prev_node(struct LinkedList *lst, int data){ 
//function that return the node before the one that contains the value of "data" 
} 
    void remove_node(struct LinkedList *lst, int data){ 
     if(lst->data == data){ 
      if(lst->next == NULL){ free(lst); } 
      else{ 
       struct LinkedList *temp = lst; 
       lst = temp->next; 
       free(temp); 
      } 
     return; 
    } 
    else{ 
     struct LinkedList *prev_node = search_ret_prev_node(lst, data); 
     if(prev_node == NULL){return;} 
     if(prev_node->next->next == NULL){ 
      free(prev_node->next); 
      prev_node->next = NULL; 
     } 
     еlse{ 
      struct LinkedList *temp= prev_node->next; 
      prev_node->next = temp->next; 
      free(temp); 
     } 
    } 
} 

int main(){ 
    struct LinkedList *list = malloc(sizeof(struct LinkedList)); 
    list->data = 4; 
    list->next = NULL 
// adding a few nodes, let's say that the first one contains the number 7 
    remove(list, 7); 
} 

Теперь, когда я сказал, что проблема в том, что после того, как я вызываю функцию удалить на первом узле, он рандомизации список, я получаю значения, аналогичные 21415135, которые не предполагают, чтобы быть в список, возможно, я получаю доступ к памяти другой программе. Я удалил некоторые детали, потому что функция работает отлично, если я пытаюсь удалить любой другой узел, отличный от первого. Любые идеи, почему это происходит?

+0

Проблема заключается в том, если вы освобождаете первый узел, указатель списка в основном становится недействительным, потому что вы удалили его! Вам нужно либо вернуть список из процедуры удаления, либо перенять запись, которая является постоянной и не может быть удалена. – Jiminion

+0

ваше имя функции 'remove_node' не просто' remove' (вы используете в главной функции для вызова) –

+1

Это односвязный список? Кто указывает на голову? –

ответ

2

Вы можете сказать, что есть проблема, как только вы видите это:

remove(list, 7); 
// ^

Смотрите что-то подозрительное? Точно, нет амперсанда! Это означает, что независимо от того, что делает remove, значение указателя list не изменится, поскольку указатель передается по значению. Следовательно, удаление первого элемента не приведет к правильному изменению списка: то, что вы в итоге получите, - это висячий указатель.

Есть два распространенных способа решения этого вопроса:

  • Сделать «фальшивый» первый узел, который всегда игнорировал или
  • передать указатель на указатель на вашей remove функции.

Я предпочитаю второй подход:

void remove(struct LinkedList **lstPtr) { 
    ... // Add an extra level of dereference 
} 
... 
remove(&list, 7); 
+1

Или верните указатель нового списка. –

+0

или удалить указатель списка. – Jiminion

+2

Jinx! Купи мне кокс. – Jiminion

0

Remove_node должен вернуть значение (возможно, обновленное), чтобы записи списка в области, из которой он был вызван, останутся действительными.

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