2016-08-30 74 views
1

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

#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"); 
} 
+2

你没有做什么用函数的返回值。参数'head'是main中的一个副本*。试试'myList = addToHead(myList,input);'。 –

+2

将'head'变成'addToHead'具有本地范围。 – LPs

回答

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返回值:它可能会失败。

+0

@Downvoter任何提示?... – LPs

0

您从addToHead返回新头节点,但你不要用它做任何事情。您需要将此值分配给myList来更新它:

myList = addToHead(myList, input); 

而且,你拼错以下行的变量:

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

它应该是:

printf("%d \n", myList->data); 
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)) 
{ 
    //... 
}