C 尝试插入到已排序的链接列表时出现分段错误

C 尝试插入到已排序的链接列表时出现分段错误,c,linked-list,C,Linked List,我只是尝试以排序的方式将随机整数插入到链表中 node_type *head=NULL; for(int i=1;i<=10;i++) { input=rand()%101; insert(input,&head); } segfault似乎是在循环遍历这段代码一次之后发生的 while( (tempHead->num)<=input && tempHead!=NULL) { prev=te

我只是尝试以排序的方式将随机整数插入到链表中

node_type *head=NULL;

for(int i=1;i<=10;i++)
 {
    input=rand()%101;
    insert(input,&head);
 }
segfault似乎是在循环遍历这段代码一次之后发生的

while( (tempHead->num)<=input && tempHead!=NULL)
       {
             prev=tempHead;
             tempHead=(*tempHead).link;
       }

这似乎是一个愚蠢的问题,但我似乎无法找出这段代码中的错误所在

您的代码中有几个微妙的问题

  • 评论中提到的那个。在while循环中,在测试tempHead是否为NULL值之前,您取消了对它的引用 以下面的表达式为例:
    (tempHead->numnumlink=temp;
    。此时,您需要处理两种情况:

    你在列表中间,

  • 您位于列表的开头,
    prev
    为空

  • 我将发布一个完整的工作示例,让您比较两者之间的差异。这是一个艰难的实践,即使是最专业的C程序员也可能忽略这些类型的缺陷

    #include <stddef.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct node_type node_type;
    
    struct node_type {
        int num;
        node_type *link;
    };
    
    node_type *head=NULL;
    
    void dump()
    {
        for(node_type *n=head; n; n=n->link)
            printf("%d ", n->num);
        printf("\n");
    }
    
    void insert(int input,node_type **  list);
    
    int main()
    {
        for(int i=1;i<=10;i++)
        {
            int input=rand()%101;
            printf("i=%d, input=%d\n", i, input);
            insert(input,&head);
        }
        dump();
    }
    
    void insert(int input,node_type **  list)
    {
        node_type * temp=malloc( sizeof(node_type));
        if(temp==NULL)
            printf("Error,memory allocation unavailable");
        memset(temp, 0, sizeof(node_type)); // [Problem 0]: Initialize the structure.
    
        temp->num=input; // filling up with the user's input
    
        node_type *tempHead=*list; 
        node_type *prev=NULL;
    
        if(tempHead==NULL) // if list is empty, I simply insert the node at start of list
        {
            //temp->link=*list; // [Problem 1]: This statement caused a loop list.
            *list=temp;//inserting it at the start of the list
            return;
        }
    
        //while( (tempHead->num)<=input && tempHead!=NULL) // [Problem 2]: wrong condition expression
        while( tempHead!=NULL && tempHead->num <= input ) // this is the correct expression order.
        {
            prev=tempHead;
            tempHead=tempHead->link;
        }
    
        if( !prev ) // tempHead != NULL but tempHead->num < input.
        {
            temp->link = *list;
            *list = temp;
        }
        else // we're in the middle of the list.
        {
            printf("%p, %p, %p, \n", prev, temp, tempHead);
            prev->link=temp; //Preceding node of new node now points to new node
            temp->link=tempHead; //new node points to succeeding node
        }
    }
    
    
    #包括
    #包括
    #包括
    #包括
    类型定义结构节点\类型节点\类型;
    结构节点类型{
    int-num;
    节点类型*链路;
    };
    节点类型*头=空;
    无效转储()
    {
    对于(节点类型*n=头部;n;n=n->link)
    printf(“%d”,n->num);
    printf(“\n”);
    }
    无效插入(整数输入,节点类型**列表);
    int main()
    {
    for(int i=1;inum=input;//填充用户的输入
    节点类型*临时头=*列表;
    节点类型*prev=NULL;
    if(tempHead==NULL)//如果列表为空,我只需在列表的开头插入节点即可
    {
    //temp->link=*list;//[Problem 1]:此语句导致循环列表。
    *list=temp;//将其插入列表的开头
    返回;
    }
    //而((tempHead->num)num链接;
    }
    如果(!prev)//tempHead!=NULL,但tempHead->num链接=*列表;
    *列表=临时;
    }
    否则我们就在名单中间了。
    {
    printf(“%p、%p、%p、\n”、上一个、临时、临时头);
    prev->link=temp;//新节点的前一个节点现在指向新节点
    temp->link=tempHead;//新节点指向后续节点
    }
    }
    
    旁注:不要这样做:(例如,
    (*temp).num
    但是,
    temp->num
    更可读。另外,对于这么小的东西,请将整个程序作为单个代码块发布。它应该能够下载、编译[干净],并运行[如果响应者选择]。在验证它是否为
    NULL
    之前,您正在对
    tempHead
    进行反引用@CraigEstey我将尝试使用箭头运算符。我只是想给出一个MRE,所以我没有发布整个程序。@StephenNewell在((tempHead->num)时不显示
    )在您取消引用后,它会检查
    tempHead
    是否为
    NULL
    。我希望切换
    操作符的左右两侧&&
    可以修复此segfault。我似乎不理解第二个问题,即我的
    prev=NULL
    。因此,我也不理解第三个问题。尽管我不理解第三个问题,如果if子句中有
    return
    语句,为什么会出现循环?抱歉,延迟了。在更新答案时发现了问题。请重新阅读并告诉我您的困惑。谢谢,我现在似乎理解了
    循环(虽然我不知道为什么您的代码没有按顺序打印它们)但不应该
    while(tempHead!=NULL&&(tempHead->num)
    while(tempHead!=NULL&&(tempHead->num)这不是一件好事吗?因为现在
    prev
    指向节点的前一个节点(
    tempHead
    )它的值比输入值大,我们现在可以正确地
    prev->link=temp
    temp->link=tempHead
    (即将新节点插入正确的位置)?
    typedef struct node_type node_type;
    
    struct node_type
    {
       int num;
       node_type *link;
    };
    
    #include <stddef.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct node_type node_type;
    
    struct node_type {
        int num;
        node_type *link;
    };
    
    node_type *head=NULL;
    
    void dump()
    {
        for(node_type *n=head; n; n=n->link)
            printf("%d ", n->num);
        printf("\n");
    }
    
    void insert(int input,node_type **  list);
    
    int main()
    {
        for(int i=1;i<=10;i++)
        {
            int input=rand()%101;
            printf("i=%d, input=%d\n", i, input);
            insert(input,&head);
        }
        dump();
    }
    
    void insert(int input,node_type **  list)
    {
        node_type * temp=malloc( sizeof(node_type));
        if(temp==NULL)
            printf("Error,memory allocation unavailable");
        memset(temp, 0, sizeof(node_type)); // [Problem 0]: Initialize the structure.
    
        temp->num=input; // filling up with the user's input
    
        node_type *tempHead=*list; 
        node_type *prev=NULL;
    
        if(tempHead==NULL) // if list is empty, I simply insert the node at start of list
        {
            //temp->link=*list; // [Problem 1]: This statement caused a loop list.
            *list=temp;//inserting it at the start of the list
            return;
        }
    
        //while( (tempHead->num)<=input && tempHead!=NULL) // [Problem 2]: wrong condition expression
        while( tempHead!=NULL && tempHead->num <= input ) // this is the correct expression order.
        {
            prev=tempHead;
            tempHead=tempHead->link;
        }
    
        if( !prev ) // tempHead != NULL but tempHead->num < input.
        {
            temp->link = *list;
            *list = temp;
        }
        else // we're in the middle of the list.
        {
            printf("%p, %p, %p, \n", prev, temp, tempHead);
            prev->link=temp; //Preceding node of new node now points to new node
            temp->link=tempHead; //new node points to succeeding node
        }
    }