大家好我是链接列表的新手,但我很确定我知道它们是如何工作的,理论上,我认为我可能会出现语法误解或内存管理错误。
edit:我的主要目的是创建一个由数组索引的列表集合,每个数组元素都是一个头(或根)节点。我有动态分配这个struct数组的问题。
我正在做的是以下内容:
typedef struct item_list{
int item_name;
int item_supplier;
int item_price;
struct item_list *next
}node;
int i;
node ** shop_1 = (node **)malloc(shop_items_elements * sizeof(node));
for (i=0;i<=shop_items_elements;i++)
{
shop_1[i]->next=NULL;
}
当我尝试在元素next
i
处NULL
时,我遇到了分段错误。
答案 0 :(得分:3)
问题是您正在尝试将20000个项目的内存分配为连续块。这意味着你实际上还没有了解链接列表。
我认为您将随机访问数组功能与纯链接列表混合在一起,不允许在不遍历列表的情况下访问单个项目。
链接列表通常包含head
和tail
节点,当列表中没有元素时,这些节点最初为NULL
:
node* head = NULL;
node* tail = NULL;
添加新节点时,首先使用大小为单个节点struct的malloc分配它:
node* the_new_node = (node*)malloc(sizeof(node));
初始化struct成员,特别是为每个新节点将next
设置为NULL。然后使用此append_node()
函数将节点附加到链接列表:
void append_node(node** head, node** tail, node* the_new_node)
{
if(*tail == NULL)
{ // list was empty
*head = *tail = the_new_node;
}
else
{
(*tail)->next = the_new_node; // link previous tail node with new one
*tail = the_new_node; // set the tail pointer to the new node
}
请注意指向更新head
和tail
指针所需指针的指针。对于您要添加的任何给定n
,请调用此函数:
append_node(&head, &tail, n);
对每个新节点重复此操作。
封装链表的更好方法是将head和tail指针放入另一个struct
typedef struct linked_list
{
node* head;
node* tail;
} list;
并使用该实例作为append_node()
的第一个参数(我将作为练习留给您;)
当使用这样的链表时,不可能可以方便地访问少于O(n)的N
节点,因为您必须遵循所有next
指针从head
节点开始,直到到达N
节点。
编辑:如果您希望能够为商店商品编制索引并从每个元素构建链接列表,我建议采用以下解决方案:
node** shop_1 = (node**)malloc(shop_items_elements * sizeof(node*));
int i;
for(i = 0; i < shop_items_elements; ++i)
{
node* n = (node*)malloc(sizeof(node));
n->next = NULL;
shop_1[i] = n;
}
首先分配一个指向node
指针的指针数组,当然这些指针必须单独分配。请查看此图表以供参考:
实际节点实例可能大于指针的大小(与图中绘制的不同),这就是为什么在块中而不是N * sizeof(node*)
分配N * sizeof(node)
的原因。
答案 1 :(得分:1)
您的代码需要看起来像这样
int i;
node * shop_1 = (node *)malloc(shop_items_elements * sizeof(node));
for (i=0;i<shop_items_elements;++i)
{
shop_1[i].next=NULL;
}
您的malloc语句已分配节点数组,而不是指向节点的指针数组。 (如果这是您想要的,那么在尝试将值分配给指向的节点内的字段之前,您将不得不使用另一个malloc调用初始化每个指针。)