2013-08-01 51 views
4

我正在爲「單一鏈接列表」編寫C代碼。在這段代碼中,我想在列表的末尾插入元素。它編譯得很好。但是在運行期間,預期的輸出不會到來。我正在使用gcc作爲編譯器。每當我在終端上做./a.out它就會被絞死。
下面是代碼:運行時錯誤:單獨鏈接列表程序插入一個值

#include<stdio.h> 
#include<stdlib.h> 
struct list 
{ 
    int node; 
    struct list *next; 
}; 

void insert(struct list *, int); 
void print(struct list *); 

int main() 
{ 
    struct list *mylist; 

    insert(mylist, 10); 
    insert(mylist, 20); 
    insert(mylist, 30); 
    insert(mylist, 40); 
    insert(mylist, 50); 
    insert(mylist, 60); 

    print(mylist); 
    return 0; 
} 

void print(struct list *head) 
{ 
    if(head==NULL) 
     return; 
    else 
    { 
      while(head->next!=NULL) 
      { 
      printf("%d\t",head->node); 
      head=head->next;  
     } 
    } 
} 


void insert(struct list *head, int value) 
{ 
    struct list *new_node; 
    new_node = (struct list *)malloc(sizeof(struct list)); 

//node Creation 
    new_node->node=value; 
    new_node->next=NULL; 

//Adding Node to list 
    if(head==NULL) 
    { 
     head=new_node; 

    } 
    else 
    { 
     while(head->next!=NULL); 
     { 
      head=head->next; 

     } 
     head->next=new_node; 

    } 

} 

這裏insert()是其功能中mylist鏈表和print()插入元件是它打印在鏈接列表中的所有的值的函數。請幫忙。我無法捕捉到我犯的錯誤。

+0

爲什麼你標記的一個問題是明確下用C++ ?沒有這樣的東西,C/C++ – nijansen

+2

mylist沒有被初始化爲NULL,但這似乎很重要。 – jxh

+0

當我將mylist初始化爲NULL時,它總是進入insert()函數的** if **部分,因此沒有鏈接列表。 – Naman

回答

4

問題是與下面的行,

while(head->next!=NULL); 

它應該是,

while(head->next!=NULL) 

刪除分號。

1

這是一個很好的無限循環。如果你使用調試器,你可以自己找到它^^。

while(head->next!=NULL); 

之後您還需要在主函數中初始化您的列表。

struct list *mylist = NULL; 

youalso需要changeyour插入參數是一個雙指針(如果你通過它的指針只因爲它只是複製地址值將不會出現在主頭列表值變化應)

void print(struct list *head) 
{ 
    while(head!=NULL) 
    { 
    printf("%d\t",head->node); 
    head=head->next;  
    } 
} 

void insert(struct list **head, int value) 
{ 
    struct list *new_node; 
    new_node = (struct list *)malloc(sizeof(struct list)); 

    //node Creation 
    new_node->node=value; 
    new_node->next=NULL; 

    //Get the end of the list 
    while((*head)->next!=NULL) 
    { 
    (*head)=(*head)->next; 
    } 

    // Add the node at the end of the list 
    (*head)->next=new_node; 
} 

int main() 
{ 
    struct list *mylist = NULL; 

    insert(&mylist, 10); 
    insert(&mylist, 20); 
    insert(&mylist, 30); 
    insert(&mylist, 40); 
    insert(&mylist, 50); 
    insert(&mylist, 60); 

    print(mylist); 
    return 0; 
} 
+2

paper.plane也指出你的插入函數參數必須是'struct list ** head'而不是'struct list * head'我會糾正我的答案 – Phong

2

有幾個錯誤:

1)您的代碼編寫者struct list *head;。你知道在C和C++中這樣的變量沒有被初始化嗎?除非它在全球範圍內,否則你不能指望它是NULL;相反,局部變量必須在使用前始終進行初始化。

2)你的插入功能按值接收head所以當它改變它(在列表爲空的情況下),它只是修改其本地副本,而不是mainhead變量。您必須通過head作爲struct list **,否則您必須將新的head值返回給main。在C++中,另一種方法是將其作爲list *&(引用指針)傳遞。

3)你while迴路有一個額外的分號身體所以它是一個空循環和身體部分將始終執行之前(不管是什麼情況),並正好一次,因爲它只是一個嵌套{...}塊。

5

我建議一個更變化,即的函數的原型應該像

void insert(struct list **, int); 
void print(struct list **); 

和主體應當相應地改變。正如你在insert中做了新的內存分配一樣,所以你不應該通過值來傳遞,而應該是通過地址,然後只有它按照預期工作。此外,在print函數中,while((head) - > next!= NULL)代替while((* head!= NULL)),循環終止應爲 ,否則它將跳過最後一個節點。

您還應該在第一次調用插入函數後將第一個節點存儲到tmp指針中,並且應該在最後將tmp指針傳遞給print函數。在你的代碼中,你將指針傳遞給最後一個錯誤的節點。所以,它應該是這樣的。

int main() 
{ 
    struct list *mylist=NULL, *tmp = NULL; 

    insert(&mylist, 10); 

    tmp = mylist; /* here */ 

    insert(&mylist, 20); 
    insert(&mylist, 30); 
    insert(&mylist, 40); 
    insert(&mylist, 50); 
    insert(&mylist, 60); 

    /* At this point mylist is pointing to last node, so pass tmp which stores the first node */ 
    print(&tmp);  
    return 0; 
} 
+0

+1:我在我的答案中錯過了一件事! – Phong

+0

實際上插入改變是需要的,但不是打印的(但我最好同意) – Phong

+0

對於print(),沒有必要使用雙重間接。 – alk

1

雖然它不能立即解決您的問題,但請注意,動態分配的內存在您的應用程序中未被釋放:程序泄漏。

這將是非常可取添加其他功能destroy

void destroy(list * head) 
{ 
    while(head != NULL) 
    { 
     struct list * tmp = head->next; 
     free(head); 
     head = tmp; 
    } 
} 

這是一個完整的工作示例,不漏:http://ideone.com/y2Fl7i

+0

+1:是的,我錯過了重要的解除分配點。 –