2013-11-13 2 views
0

Я пытаюсь реализовать deleteDuplicates, учитывая связанный список в C. Я столкнулся с проблемами с segFault, и я не уверен, почему. Мой тестовый пример дает ему связанный список с двумя узлами, каждый с данными 3 ниже. В моих deleteDups вы увидите два закомментированных if-блока. Если я раскомментирую это, у меня не будет segFault, и код будет работать нормально.deleteDuplicates single-linkedlist C

Почему это так? Мне кажется, что утверждение if - это именно то, что проверяет цикл while ...

Заранее благодарен!

моя структура узла и код

typedef struct node{ 
    int data; 
    struct node *next; 
} *node; 


void deleteDups(node *head) 
{ 
    if (!*head) 
     return; 
    node current = *head; 
    node runner; 
    while (current) 
    { 
     runner = current; 
     while (runner->next) 
     { 
      if (runner->next->data == current->data) 
      { 
       node tmp = runner->next; 
       runner->next = runner->next->next; 
       free(tmp); 
      } 
      /*if(runner->next == NULL) 
      { 
       break; 
      }*/ 
      runner = runner->next; 

     } 
     /*if (current->next == NULL) 
     { 
      break; 
     }*/ 
     current = current->next; 
    } 

} 

int main(int argc, char*argv[]) 
{ 

node one = (node) malloc (sizeof (struct node)); 
one->data = 3; 
one->next = NULL; 

node head = (node) malloc (sizeof (struct node)); 
head->data = 3; 
head->next = one; 

printList(head); 
deleteDups(&head); 
printList(head); 

return 0; 

}

ответ

1

Проблема находится в состоянии внутреннего цикла и назначение

runner = runner->next; 

Поскольку у вас есть только два узла, и удалить последний , вышеприведенное присвоение составит runner, равное NULL. Затем вы проверяете на runner->next в состоянии цикла.

Это было бы очень легко найти в отладчике, особенно если вы использовали его для перехода по коду по строчке, чтобы узнать, что произошло. Я рекомендую попробовать в следующий раз.

1

Причина, по которой это происходит: В конце первой итерации внутреннего цикла while значение runner равно нулю, а вызов операции -> следующий результат segfault.

Пошаговое разработать как выше: сложилось,

У вас есть связанный список из двух узлов. В начале внутреннего контура в то время как ниже,

runner points to the first node,  
runner->next points to second node, and  
runner->next->next points to null 

В конце первой итерации, есть только один узел и, следовательно, runner-> следующая равна нулю. (После первого прокомментированного оператора if) бегуну присваивается значение runner-> next. Таким образом, значение runner теперь равно NULL.

В начале следующей итерации, check runner-> next приводит к segFault, поскольку бегун имеет значение NULL.

- Кроме того, чтобы убедиться, что функция работает для пустого списка, вы должны проверить, если (голова!), А если (* голова!)

0

Проблема, кажется, в вашем NULL проверьте для runner-> next.Когда вы выполните эти две строки для последнего узла в списке, ваш бегун станет NULL.

runner->next = runner->next->next; < --- Следующий номер бегуна здесь NULL.

.....

runner = runner->next; < - Runner теперь NULL.

В следующей итерации бегун-> следующий сбой. состояние в то время как цикл должен быть таким: while(runner & runner->next)

-MS

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