为链接列表数组分配内存

时间:2014-05-26 19:27:00

标签: c arrays memory-management struct linked-list

大家好我是链接列表的新手,但我很确定我知道它们是如何工作的,理论上,我认为我可能会出现语法误解或内存管理错误。

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 iNULL时,我遇到了分段错误。

2 个答案:

答案 0 :(得分:3)

问题是您正在尝试将20000个项目的内存分配为连续块。这意味着你实际上还没有了解链接列表。

我认为您将随机访问数组功能与纯链接列表混合在一起,不允许在不遍历列表的情况下访问单个项目。


链接列表通常包含headtail节点,当列表中没有元素时,这些节点最初为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
  }

请注意指向更新headtail指针所需指针的指针。对于您要添加的任何给定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指针的指针数组,当然这些指针必须单独分配。请查看此图表以供参考:

enter image description here

实际节点实例可能大于指针的大小(与图中绘制的不同),这就是为什么在块中而不是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调用初始化每个指针。)