链表分段故障

时间:2016-10-21 01:02:31

标签: c linked-list

我正在练习编写一个链接列表,该列表将以升序从用户那里获取数字,并告诉您所使用的唯一数字是什么。在我的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;
}

3 个答案:

答案 0 :(得分:2)

错误1:

node-inspector --web-port=8099 bin/www

应该是

addterm(Number_List, digit);

您忘了更新列表指针。

错误2:

Number_List = addterm(Number_List, digit);

应该是

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

这会产生一个无限循环。

错误3:

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

应该是

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

新节点没有下一个节点集。这也产生了一个无限循环。

错误4:

newNum->next = NULL;

应该是

if(print == temp){
        continue;
}

另一个无限循环。

答案 1 :(得分: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;
}

答案 2 :(得分:0)

这些都是很好的答案,他们肯定会帮助你解决这个问题。

但是,我建议如下:这个问题的真正答案是,这是一个你可能知道的链表:

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

你可能遇到的最大危险是你的下一个和开始指针。现在以一种始终帮助您执行以下操作的方式回答您的问题:

  1. 在IDE中启用调试并在程序入口点中放置断点。快速使用Step over工具,直到程序出现故障。现在您知道导致它的那条线。

  2. 在该行上放置一个断点并调试到该位置,并确定何时设置导致问题的指针。

  3. 许多IDE提供了一个工具来放置一个手表&#39;只有当您指定的变量等于您指定的值时,才会在一个点上破坏程序的变量,在这种情况下,我建议使用NULL。

  4. 由于您现在正在获取段错误,因此您需要查看有循环的位置,因为您可能会超出列表的范围。

  5. 学习调试技巧是解决此问题的正确方法!

    祝你好运!