2016-10-21 2 views
0

사용자로부터 오름차순으로 숫자를 가져 와서 사용한 고유 번호가 무엇인지 알려주는 연결 목록을 작성하여 연습하고 있습니다. 내가 findUnique 함수를 indener 한 후 세그먼테이션 오류가 계속 발생하고, while 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가 호출되고 list-> num 및 ** BOOM ** – MatzZze

+0

Bah에 액세스하고 있습니다. 위에서 내가 할 수있는 유일한 제안은 마지막 조건을'if (print! = temp) { temp = print; printf ("% d", temp); }'. 이것은 읽기가 더 쉽고, 처음부터 문제가되는'continue'를 피합니다. –

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. IDE에서 디버깅을 활성화하고 프로그램 엔트리 포인트에 중단 점을 배치하십시오. 프로그램이 잘못 될 때까지 급속 발사 도구를 사용하십시오. 이제 당신은 어떤 라인이 그 원인인지 알 수 있습니다.

  2. 해당 줄에 중단 점을 놓고 해당 지점으로 디버그하고 문제를 일으키는 포인터가 설정되는시기를 결정합니다.

  3. 많은 IDE는 지정한 변수가 지정한 값과 같은 경우에만 한 점에서 프로그램을 중단시키는 변수에 '감시'를 배치하는 도구를 제공합니다.이 경우 NULL을 권합니다.

  4. 지금부터 세그 폴트가 발생하므로 목록의 범위를 반복 할 가능성이 있으므로 루프가있는 곳을 살펴볼 필요가 있습니다.

이 문제에 대한 올바른 해결책은 학습 디버깅 기술입니다.

행운을 빌어 요!