2016-08-01 98 views
-3

我正在處理單個鏈表並且無法解決問題(我認爲問題是在添加函數時使用NULL指針),問題是它只添加第一個數字來列表並跳過休息呼叫添加功能。無法理解c中的空指針

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

struct node 
{ 
    int i; 
    struct node* next; 
}; 

struct node* head = NULL; 

int add(int val) 
{ 
    if(head == NULL) 
    { 
    head = (struct node*)malloc(sizeof(struct node)); 
    head->i = val; 
    } 
    else 
    { 
    struct node* current = head; 
    while(current != NULL) 
    { 
     current = current->next; 
    } 
    current = (struct node*)malloc(sizeof(struct node)); 
    current->i = val; 
    } 
} 

int print(struct node* first) 
{ 
    while(first != NULL) 
    { 
    printf("%d\n",first->i); 
    first = first->next; 
    } 
} 

int main() 
{ 
    add(36); 
    add(46); 
    add(97); 
    print(head); 
    return 0; 
} 
+1

@underscore_d這就是所謂的C++,如果你想試着阻止人們詢問關聯鏈表的問題,那麼這就是無關緊要的。 – immibis

回答

2

這裏有兩個問題。首先,在創建新節點時,不要將next設置爲NULL。所以當你遍歷列表時,你最終會讀取垃圾數據,調用undefined behavior

然後接下來的問題是,當你遍歷一個非空列表時,你從列表的末尾「脫落」,所以current在循環結束時爲NULL,並且沒有鏈接到列表的末尾。當current->next爲空時,您需要停止,然後在那裏創建新節點。

void add(int val)  // change return type to void since nothing is being returned 
{ 
    if(head == NULL) 
    { 
    head = malloc(sizeof(struct node)); // don't cast return value of malloc 
    head->i = val; 
    head->next = NULL;     // terminate list 
    } 
    else 
    { 
    struct node* current = head; 
    while(current->next != NULL)   // loop until you're on the last node 
    { 
     current = current->next; 
    } 
    current->next = malloc(sizeof(struct node)); 
    current->next->i = val; 
    current->next->next = NULL;   // terminate list 
    } 
} 
+0

我認爲未初始化的指針與c中的NULL指針相同,這幫助我清除了疑問。 –

+0

@neeraj_nigam還有一個選項可以用'calloc'初始化每個節點。有關更多信息,請參閱[這裏](http://en.cppreference.com/w/c/memory/calloc)。調用語法有點不同,但不是太瘋狂。 – callyalater

2

你永遠設置node->nextNULL(用於head->nextcurrent->next路徑)。使用malloc進行分配不會清除分配的內存,因此您需要自行完成此操作。

此外,當您添加的第二個元素,你迭代直到current達到NULL,但你永遠不設置previous_node->next指向新的元素,所以你從來沒有真正「鏈接」在你的鏈表什麼。

另外,你shouldn't cast the result of malloc in C

2

最主要的原因,爲什麼你沒有看到添加第二和後續節點的作用是,當你分配一個新的節點不是頭節點,你的存儲指向它只能在局部變量current的功能add()。您需要將其存儲在前一節點的next指針中。與原來的代碼比較:

struct node* current = head; 
    while (current->next != NULL) { 
     current = current->next; 
    } 
    current->next = malloc(sizeof(*current->next)); 

還要注意的是,作爲@Lousy也觀察到,你沒有新節點的next指針設置爲NULL。您必須這樣做,直到您爲這些字段分配一些值,其內容是不確定的。