2016-10-21 4 views
0

Я занимаюсь написанием связанного списка, который будет принимать цифры от пользователя в порядке возрастания и рассказать вам, какие уникальные номера вы использовали. Я продолжаю получать ошибку сегментации после того, как она указывает на мою функцию findUnique и мой цикл while, который я настроил для распечатки списка, прежде чем он войдет, не печатает ничего. Это просто практика со связанным списком, поэтому любая помощь будет оценена по достоинству.Ошибка сегментации связанного списка

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

typedef struct number{ 

    int num; 
    struct number* next; 
}Number; 

Number *addterm(Number*, int); 
void findUnique(Number*); 

int main(void){ 

    Number *Number_List = NULL; 
    int digit = 1; 

    printf("Enter numbers in ascending order(enter 0 to stop): "); 
    scanf("%d", &digit); 

    while(digit != 0){ 
     addterm(Number_List, digit); 
     printf("Enter numbers in ascending order(enter 0 to stop): "); 
     scanf("%d", &digit); 
    } 
    printf("\ntest 1\n"); 

    Number *ptr = Number_List; 
    while(ptr){ 
     printf("%d ", ptr -> num); 
     Number_List = ptr -> next;   
    } 
    printf("\ntest 2\n"); 
    printf("\n"); 

    findUnique(Number_List); 


    return 0; 
} 

Number *addterm(Number* list, int userIn){ 
    Number *newNum = (Number *) malloc (sizeof (Number)); 
    newNum->num = userIn; 
    newNum->next = list; 

    if(list == NULL){ 
     return newNum; 
    } 
    Number *ptr = list; 

    while(ptr->next != NULL){ 
     ptr = ptr->next; 
    } 
    ptr->next = newNum; 
    return list; 
} 
void findUnique(Number* list){ 

    int print, temp; 
    print = list->num; 
    temp = print; 
    printf("The unique numbers you entered are %d", temp); 

    while(list){ 
     print = list->num; 
     if(print == temp){ 
      continue; 
     } 
     else{ 
     temp = print; 
     printf(" %d", temp); 
     } 
     list = list -> next; 
    } 
    return; 
} 
+2

Добро пожаловать в переполнение стека! Похоже, вам, возможно, потребуется научиться использовать отладчик для выполнения вашего кода. С хорошим отладчиком вы можете выполнить свою программу по очереди и посмотреть, где она отклоняется от ожидаемого. Это важный инструмент, если вы собираетесь заниматься программированием. Дальнейшее чтение: [Как отлаживать небольшие программы] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

ответ

2

Ошибка 1:

addterm(Number_List, digit); 

должен быть

Number_List = addterm(Number_List, digit); 

Вы забыли обновить список указатель.

Ошибка 2:

while(ptr){ 
    printf("%d ", ptr -> num); 
    Number_List = ptr -> next;   
} 

должно быть

while(ptr){ 
    printf("%d ", ptr -> num); 
    ptr = ptr -> next;   
} 

Это генерируя петлю бесконечности.

Ошибка 3:

newNum->next = list; //In addTerm() 

должен быть

newNum->next = NULL; 

Новые узлы не имеют следующий набор узлов. Это также создало цикл бесконечности.

Ошибка 4:

if(print == temp){ 
     continue; 
} 

должно быть

if(print == temp){ 
     list = list->next; 
     continue; 
    } 

Другой цикл бесконечности.

+0

Segfault - это результат ** Ошибка 1 **. Вы забыли обновить указатель, чтобы Number_List всегда был NULL. Затем findUnique вызывается, и вы получаете доступ к списку-> num и ** BOOM ** – MatzZze

+0

Ба, вы избили меня тоже! Единственное предложение, которое я могу сделать выше, - это изменить последнее условие на 'if (print! = Temp) {temp = print; printf ("% d", temp); } '. Это проще читать и позволяет избежать «продолжения», что привело вас к проблеме в первую очередь. –

0

У меня была попытка решить эту проблему, и я считаю, что ошибка в вашей функции findUnique. Эти вопросы уже затронуты ниже @MatzZze, и это поможет исправить ваш текущий код.

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

Здесь:

#include <stdio.h> 
#include <stdlib.h> 

typedef int data_t; 

typedef struct node node_t; 

struct node { 
    data_t num; 
    node_t *next; 
}; 

typedef struct { 
    node_t *head; 
    node_t *foot; 
}list_t; 

list_t *make_empty_list(void); 
list_t *add_term(list_t *list, data_t value); 
void read_terms(list_t *list); 
void print_unique_terms(list_t *list); 
list_t *unique_terms(list_t *list); 
void print_list(list_t *list); 
void free_list(list_t *list); 

int 
main(int argc, char const *argv[]) { 
    list_t *list; 

    list = make_empty_list(); 

    read_terms(list); 

    printf("Your numbers are:\n"); 
    print_list(list); 

    unique_terms(list); 

    printf("The unique numbers you entered are:\n"); 
    print_list(list); 

    free(list); 

    return 0; 
} 

void 
read_terms(list_t *list) { 
    int digit; 

    printf("Enter numbers in ascending order(enter 0 to stop): "); 
    while (scanf("%d", &digit) == 1) { 
     if (digit == 0) { 
      break; 
     } else { 
      add_term(list, digit); 
     } 
    } 
} 

list_t 
*add_term(list_t *list, data_t value) { 
    node_t *node; 
    node = malloc((sizeof(*node))); 
    node->num = value; 
    node->next = NULL; 

    if (list->foot == NULL) { 
     list->head = list->foot = node; 
    } else { 
     list->foot->next = node; 
     list->foot = node; 
    } 
    return list; 
} 

list_t 
*unique_terms(list_t *list) { 
    node_t *node = list->head; 

    while (node != NULL && node->next != NULL) { 
     if (node->num == node->next->num) { 
      node->next = node->next->next; 
     } else { 
      node = node->next; 
     } 
    } 
    return list; 
} 

void 
free_list(list_t *list) { 
    node_t *curr, *prev; 
    curr = list->head; 
    while (curr) { 
     prev = curr; 
     curr = curr->next; 
     free(prev); 
    } 
    free(list); 
} 

void 
print_list(list_t *list) { 
    node_t *node = list->head; 

    while (node != NULL) { 
     printf("%d ", node->num); 
     node = node->next; 
    } 
    printf("\n"); 
} 

list_t 
*make_empty_list(void) { 
    list_t *list; 
    list = malloc(sizeof(*list)); 
    list->head = NULL; 
    list->foot = NULL; 
    return list; 
} 
0

Эти большие ответы, и они, безусловно, поможет вам с этим кодом.

ОДНАКО, я предлагаю следующее: Реальный ответ на этот вопрос в том, что это связанный список, как вы, наверное, знаете:

+------+  +------+  +------+ 
| data |  | data |  | data | 
+------+  +------+  +------+ 
| next |---->| next |---->| next |----> NULL 
+------+  +------+  +------+ 
^
    | 
START (Keep track of the whole list.) 

Самые большие опасности, вы можете столкнуться с вашим рядом и начать указатели ,Теперь, чтобы ответить на ваш вопрос в пути, который всегда поможет вам сделать следующее:

  1. Включить отладку в интегрированной среде и поместить точку останова в вашей программе EntryPoint. Используйте инструмент «Step over» в режиме быстрого огня до тех пор, пока программа не сработает. Теперь вы знаете, какая строка вызывает его.

  2. Место точки разрыва на этой линии и отладка в это место и определить, когда установлен указатель, который вызывает проблему.

  3. Многие IDE предлагают инструмент для размещения «вахты» на переменной, которая разбивает программу в точке, только если указанная вами переменная равна указанному вами значению, в этом случае я бы посоветовал NULL.

  4. Поскольку прямо сейчас вы получаете segfaults, вам нужно будет искать места, где у вас есть циклы, поскольку вы, вероятно, повторяете границы своего списка.

Изучение методов отладки - правильное решение этой проблемы!

Удачи вам!

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