2013-06-03 51 views
1

對於下面的鏈接列表聲明,鏈表實現差異

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

typedef struct list 
{ 
    int val; 
    struct list *next; 
} list; 


void destroy (list *l) 
{ 
    if (l) 
    { 
     destroy (l->next); 
     free (l); 
    } 
} 

爲什麼以下主要工作

int main() 
{ 
    list *test; 
    list *ptr1, *ptr2; 
    int i; 
    test = malloc (sizeof (list)); 
    test->val = 0; 
    ptr2 = test; 
    for (i = 1; i <= 10; i++) 
    { 
     ptr1 = (list *) malloc (sizeof (list)); 
     ptr1->val = i; 
     ptr2->next = ptr1; 
     ptr2 = ptr1; 
    } 
    ptr1 = test; 
    while (ptr1) 
    { 
     printf ("%d\n", ptr1->val); 
     ptr1 = ptr1->next ; 
    } 
    destroy (test); 
    return 0; 
} 

,而這其中甚至不創建一個列表(它只會讓一個節點)?

int main() 
{ 
    list *test; 
    list *ptr; 
    int i; 
    test = malloc (sizeof (list)); 
    test->val = 0; 
    ptr = test->next; 
    for (i = 1; i <= 10; i++) 
    { 
     ptr = (list *) malloc (sizeof (list)); 
     ptr->val = i; 
     ptr = ptr->next; 
    } 
    ptr = test; 
    while (ptr) 
    { 
     printf ("%d\n", ptr->val); 
     ptr = ptr->next ; 
    } 
    destroy (test); 
    return 0; 
} 

難道他們不使用相同的邏輯嗎?

回答

3

代碼

ptr = test->next; 
for (i = 1; i <= 10; i++) 
{ 
    ptr = (list *) malloc (sizeof (list)); 
    ptr->val = i; 
    ptr = ptr->next; 
} 

開始通過採取test->next副本,但從未指定任何東西test->next本身。因此從test開始的列表僅具有單個項目。更糟的是,該項目有一個未初始化的next指針,因此試圖迭代列表的代碼幾乎肯定會崩潰。

正如在其他答案中暗示的那樣,對於每個新分配的節點都重複該模式。

在回答您的意見時,讓第二個函數工作的最好方法是使它更像第一個(工作)版本。我已經更名爲其中的變量,試圖使其更清晰

list *head; 
list *next, *curr; 
int i; 
head = malloc (sizeof(*head)); 
head->val = 0; 
curr= head; 
for (i = 1; i <= 10; i++) 
{ 
    next = malloc (sizeof(*next)); 
    next->val = i; 
    curr->next = next; 
    curr= next; 
} 
curr= head; 
+0

我該如何改變第二個主要,以便它能工作? (假設我不會來第一個主) –

+0

@KudayarPirimbaev我已經更新了我的回答來覆蓋這個。如果沒有意思,你需要讓你的代碼看起來更像你發佈的工作版本。 – simonc

+0

好的,謝謝,我明白了 –

1

在第二主期間

ptr = test->next; 

您嘗試存取權限測試 - >未來withouth的用於it.You分配內存可以試着改變你的代碼如下得到第二個主要工作

test = malloc (sizeof (list)); 
    test->val = 0; 
    test->next = (list *) malloc (sizeof (list)); 
    ptr = test->next; 
    for (i = 1; i <= 10; i++) 
    { 
     ptr->val = i; 
    ptr->next = (list *) malloc (sizeof (list)); 
     ptr = ptr->next; 
    } 
1

它看起來像在第一個例子,它的工作原理,ptr2持有在列表前面創建的節點,因此T帽子可以重寫

last_created_node = test; 
for (i = 1; i <= 10; i++) 
{ 
    // create new node 
    new_node = (list *) malloc (sizeof (list)); 
    new_node ->val = i; 
    // chain newly created node onto list so far 
    // make last created node point to new node 
    last_created_node->next = new_node ; 
    // last created node is now new node 
    last_created_node = new_node ; 
} 
// terminate the list 
last_created_node->next = 0; 

在給出的第二個代碼示例中沒有將新節點鏈接到鏈上的等價物。其他人評論過的單元化內存也存在問題。如上面我的示例最後一行所示,添加終止條件會很好。