2016-08-30 4 views
1

Я новичок в C и попытаюсь узнать, как реализовать C в связанном списке. Я действительно смущен, почему я не могу получить доступ к myList в главной функции? потому что, когда я пытаюсь сделать myList->data, это ошибка сегментации. Я думаю, что есть некоторая ошибка в моей функции addtohead? Ниже мой код:Ошибка сегментации в связанном списке с помощью 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' является * копией * той, что находится в основном. Попробуйте 'myList = addToHead (myList, input);'. –

+2

'head' в' addToHead' имеет локальную область. – LPs

ответ

0

Ваш addToHead функция должна возвращать обратно вызывающей программе mallocat.

Таким образом, вы должны присвоить возвращаемое значение 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)) 
{ 
    //... 
}