C编程分段故障链表程序

时间:2013-04-05 01:41:48

标签: c pointers linked-list segmentation-fault

我对c(和这个网站)相当新,我遇到了很多关于分段错误的问题。我正在编写一个程序,它创建一个数字链接列表并按升序插入值。

     void insert(struct element **head, struct element *new){   
            if((*head)->next == NULL && (*new).i > (*(*head)->next).i){
                (*head)->next = new;
                return;     
            }
            if((*head)->next == NULL && (*new).i < (*(*head)->next).i){
                new->next = (*head)->next;
                *head = new;    
                return;
            }
            struct element *prev = *head;
            struct element *current = (*head)->next;
            while(current->next != NULL){
                if((*new).i < (*current).i){
                    prev = current;
                    current = current->next;
                } else if((*new).i > (*current).i){
                    new->next = current;
                    prev->next = new;
                }
            }
        }
        int main (void){
            struct element **head;
            int value;
            printf("%s", "TEST" );
            printf("%s" , "Please type in an integer value. ");
            scanf("%d" , &value);
            printf("%s", "TEST" );
            do{
                printf("%s", "TEST" );
                struct element *new;
                if((new = malloc(sizeof(struct element))) == NULL){
                return(NULL);
                }
                printf("%s", "TEST" );
                (*new).i = value;
                printf("%s", "TEST" );
                if(head == NULL){
                    *head = new;
                    printList(*head);
                }  else if(value <= 0){
                    printListBackwards(*head);
                }   
                else {

                    insert(head, new);
                    printList(*head);
                }
                } while(value > 0);

关于插入或任何东西的逻辑是否正确,我都不需要帮助。我甚至没有机会真正测试它,因为我在提示后输入一个整数后立即出现分段错误。我知道它似乎很时髦,但规范要求你使用指向结构指针的指针(链表的头部)。

3 个答案:

答案 0 :(得分:2)

您确定要成为element**而不是element*吗?这种额外的分离程度会给你带来麻烦,其中最重要的是难以阅读的代码。

这是跳出来的主要内容:

if(head == NULL){
    *head = new;
    printList(*head);
}

您确认head是一个NULL指针,然后立即尝试使用*取消引用它。如果你真的坚持将head作为双指针,那么你需要在解除引用之前动态分配它。像这样:

if(head == NULL){
    head = malloc(sizeof(element*));
    *head = new;
    printList(*head);
}

实际上可能在语法上并不完美(我来自C ++),但你明白了。说到C ++,在C中命名变量“new”通常被认为是不好的做法,因为new是C ++中的关键字。

答案 1 :(得分:0)

在帖子的第二行引起了一个段错误

if((*head)->next == NULL && (*new).i > (*(*head)->next).i){
    (*head)->next = new;
    return;     
}

分段错误意味着您正在尝试访问不允许的内存。例如,您不能取消引用NULL指针。

您的if语句的评估方式如下。 检查(*head)->next是否为空。

如果它不是NULL,则跳过其余部分。

如果它为空,那么您可以用(*head)->next替换每个NULL。这意味着以下部分&& (*new).i > (*(*head)->next.i)可以重写如下&& (*new).i > ((*NULL).i) ...

简而言之,您正尝试取消引用NULL指针值。

请参阅@Parker Kemp的帖子。有很多次你正确地检查NULL但误解了它的含义。

我可以为你重写代码,但我认为通过像this onethis one这样的教程可以获得更多好处

我强烈建议您绘制数据结构图并绘制指针箭头。

答案 2 :(得分:0)

struct element **head;

你不想那样。取而代之的是,

struct element *head = NULL;

然后,当您调用insert时,请使用

insert(&head, new);

您还有许多其他错误和不良用法,但这是您特定问题的开始。