基于C的链表上的分段错误

时间:2016-08-30 13:34:18

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

我是C的新手并尝试学习如何在链表上实现C.我真的很困惑为什么我不能在主函数中访问myList?因为当我尝试myList->data时,它的分段错误。我认为我的addtohead功能有一些错误? 以下是我的代码:

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

typedef struct NODE{
    int data;
    struct NODE *next;
}node;

node * myList;

node * addToHead(node*, int);
void printList();

int main(){
    myList = NULL;
    int input;
    while (scanf("%i",&input) == 1){
           addToHead(myList, input);
           printf("%d \n", myList->data);
       }

    printf("My List:\n");
    printList(myList);
    return 0;
}

node* addToHead(node* head, int newData){
    node *temp = (node *)malloc(sizeof(node));
    temp -> data = newData;
    temp -> next = NULL;
    if(head != NULL){
        temp -> next = head;
        }
    head = temp;
    return head;
}

void printList(node* head){
    node *temp = head;
    while(temp != NULL){
        printf("%d ", temp->data);
        temp = temp -> next;
    }
    printf("\n");
}

3 个答案:

答案 0 :(得分:0)

您从addToHead返回新的头节点,但您没有对其执行任何操作。您需要将此值指定给myList才能更新它:

myList = addToHead(myList, input);

此外,您拼错了以下行中的变量:

printf("%d \n", myListd->data);

应该是:

printf("%d \n", myList->data);

答案 1 :(得分:0)

你的addToHead函数应该将mallocat ed内存返回给调用者。

所以你应该首先将返回值分配给mylist:

int main(){
    node *myList = NULL;
    int input;
    while (scanf("%i",&input) == 1){
           myList = addToHead(myList, input);
           printf("%d \n", myList->data);
       }

    printf("My List:\n");
    printList(myList);
    return 0;
}

进入你编写的addToHead函数

head = temp;

但是head具有局部范围,并且指定的值不会反映到指针myList

要这样做,你必须使用指向指针。

int main(){
    node *myList = NULL;
    int input;
    while (scanf("%i",&input) == 1)
    {
       if (addToHead(&myList, input) == true)
       {
           printf("%d \n", myList->data);
       }
       else
       {
           fprintf(stderr, "Error addToHead\n");
       }
    }

    return 0;
}

bool addToHead(node** head, int newData){
    node *temp = malloc(sizeof(node));
    if (temp != NULL)
    {
       temp -> data = newData;
       temp -> next = NULL;
       if(head != NULL)
       {
          temp -> next = *head;
       }

       *head = temp;

       return true;
   }

   return false;
}

最后始终记得检查malloc返回值:它可能会失败。

答案 2 :(得分:0)

在此功能定义中

node* addToHead(node* head, int newData){
    node *temp = (node *)malloc(sizeof(node));
    temp -> data = newData;
    temp -> next = NULL;
    if(head != NULL){
        temp -> next = head;
        }
    head = temp;
    return head;
}

参数node* head是函数的局部变量。参数的任何更改都不会影响原始参数。退出函数后,函数参数将被销毁。

您可以通过以下方式考虑函数定义及其调用

addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
    node *head = myList;
    int newData = input;

    node *temp = (node *)malloc(sizeof(node));
    temp -> data = newData;
    temp -> next = NULL;
    if(head != NULL){
        temp -> next = head;
        }
    head = temp;
    return head;
}

因此在函数调用后不会更改原始变量myList。您必须将返回值明确指定给变量

myList = addToHead(myList, input);

此功能也有缺点。如果未分配新节点,它不会报告错误。

编写函数的更好方法看起来如下

int /* _Bool */ addToHead( node **head, int newData )
{
    node *temp = ( node * )malloc( sizeof( node ) );
    int /* _Bool */ success = temp != NULL;

    if ( success )
    {
        temp -> data = newData;
        temp -> next = *head;
        *head = temp;
    }

    return success;
}

在这种情况下,可以通过以下方式循环调用该函数

while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
    //...
}