[英]Linked list implementations difference
對於以下鏈接列表聲明,
#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;
}
他們不使用相同的邏輯嗎?
編碼
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;
在第二主要期間
ptr = test->next;
您正在嘗試訪問test-> next,而沒有為其分配內存。您可以嘗試按以下方式更改代碼以獲取第二個主要工作
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;
}
看起來在第一個示例中ptr2
, ptr2
將先前創建的節點保存在列表中,因此可以將其重寫
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;
在您提供的第二個代碼示例中,沒有等效的方法將新節點鏈接到鏈上。 正如其他人所評論的,統一內存也存在問題。 如上面示例的最后一行所示,添加終止條件會很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.