2016-08-30 97 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)) 
{ 
    //... 
}