链接列表错误"分段错误"核心倾倒

时间:2017-02-28 11:00:44

标签: c list pointers linked-list singly-linked-list

尝试在Fedora gcc上使用以下代码,将一个简单的链接列表添加到列表的尾部。编译时没有错误。在执行期间,它显示Segmentation Fault,Core Dumped。 在MS Windows上,它正在运行。

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

struct Node
{
    int data;
    struct Node *next;
};

void insertion(struct Node *);
void display(struct Node *);

int main(void)
{
    struct Node *head;
    head=NULL;
    head->next=NULL;

    int choice, cont;

    do
    {
        printf("1.Insert      2.Display       3.Exit");
        scanf("%d",&choice);

        if(choice==1)
        {
            insertion(head);
        }
        else if(choice==2)
        {
            display(head);
        }
        else if(choice==3)
        {
            exit(0);
        }
        else
        {
            printf("Wrong choice");
        }
        printf("Continue? Press 1 otherwise 0:");
        scanf("%d",&cont);
    }while(cont==1);

    return 0;
}

void insertion(struct Node *start)
{
    int data;
    struct Node *temp=NULL;
    temp->next=NULL;
    struct Node *mnew=NULL;
    mnew->next=NULL;

    mnew=(struct Node *)malloc(sizeof(struct Node));

    printf("Enter data:");
    scanf("%d",&data);

    mnew->data=data;

    if(start==NULL)
    {
        start=mnew;
    }
    else if(start!=NULL && start->next==NULL)
    {
        start->next=mnew;
    }
    else
    {
        temp=start;
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        temp->next=mnew;
    }
}

void display(struct Node *start)
{
    struct Node *temp=NULL;
    temp->next=NULL;    
    if(start==NULL)
    {
        printf("\nNothing to display!");
    }
    else if(start!=NULL && start->next==NULL)
    {
        printf("%d",start->data);
    }
    else
    {
        temp=start;
        while(temp!=NULL)
        {
            printf("%d",temp->data);
            temp=temp->next;
        }
    }
}

感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

head=NULL;
head->next=NULL;

这段代码永远无法正常工作,因为如果head的属性指向NULL(又名无处),则无法访问或赋值。

答案 1 :(得分:2)

仔细看看,例如这两行来自insertion函数:

struct Node *temp=NULL;
temp->next=NULL;

第一个定义指向struct Node的指针并使其成为空指针。下一行您取消引用此空指针,该指针无效并导致未定义的行为

你在多个地方遇到同样的问题,两者都是这样的,并且一般也会解除引用空指针。

答案 2 :(得分:1)

您可能无法使用空指针访问数据。因此,此代码段(和类似的代码片段)

struct Node *head;
head=NULL;
head->next=NULL;
^^^^^^^^^^^^^^^

无效。

对于函数insertion,您必须通过引用传递头部。否则该函数将处理头部的副本,并且函数中头部副本的任何更改都不会影响原始头部。

此外,如果存储器分配失败,则希望该功能发出信号。因此,不是返回类型void,最好使用返回类型int

所以函数声明看起来像

int insertion( struct Node ** );
^^^            ^^^^^^^^^^^^^^

该功能可以定义为

int insertion( struct Node **start )
{
    int data;

    printf( "Enter data: " );
    scanf( "%d", &data );

    struct Node *temp = ( struct Node * )malloc( sizeof( struct Node ) );

    int success = temp != NULL;

    if ( success )
    {
        temp->data = data;
        temp->next = NULL;

        while ( *start ) start = &( *start )->next;

        *start = temp;
    }

    return success;
}

可以通过以下方式调用该函数

insertion( &head );

函数display可能看起来像

void display( struct Node *start )
{
    if ( start == NULL )
    {
        printf( "\nNothing to display!\n" );
    }
    else 
    {
        for ( ; start; start = start->next )
        {
            printf( "%d ", start->data );
        }
        putchar( '\n' );
    }
}

答案 3 :(得分:0)

如上一条评论所示,未定义NULL指向另一个NULL的指针(导致指针应该保存一个地址)。 现在提出一些建议:

1)像这样定义结构:

typedef struct Node *node_pointer;

这样可以更容易地为该结构定义指针。

2)

mnew=malloc(sizeof(*mnew)); //this is easier, and this should be before the ..->next=NULL;

还要检查分配是否成功:

if (!mnew)
  return; //return something needed