这段代码有很多问题,我认为你最好阅读更多关于指针和参数传递的内容。但是这里有几件事:
当您在函数中声明“列表”时,main
它已经在堆栈上分配。add
然后,您尝试在函数中重新分配它。
如果要在add
函数中分配节点,需要通过引用传递一个指针,即指向指针的指针。这是因为否则指针是按值传递的,当函数返回时,对它的所有更改(即实际指针,而不是它指向的指针)都将丢失。
该malloc
函数不会清除分配的内存。如果您希望这种情况自动发生,您应该使用该calloc
功能。
您不会将节点链接到列表中,您只需用(未初始化的)nast
指针覆盖列表头。
您typedef
在结构中使用,但实际上并未为此定义名称typedef
。
请,哦,请不要使用goto
!如果经常使用它可能会使您的代码非常难以阅读和遵循(而且如果使用太多,很多人会争辩说,即使使用一次也太多了)。
如果我这样做,我会让我的add
函数引用一个指针作为参数,连同要添加到列表中的值。然后,我将为该值分配一个新节点,并通过使next
指针指向旧列表将其链接到列表中,然后重新分配列表指针以指向新节点。如果传递的列表是NULL
,则只需使列表指向新节点。
像这样的东西:
struct node
{
struct node *next;
double value;
};
void add(struct node **l, const double value)
{
/* Allocate a new node, use `calloc` to clear the memory automatically */
struct node *n = calloc(1, sizeof(struct node));
/* Set the value of the new node */
n->value = value;
/* Is the list non-null? */
if (*l != NULL)
{
/* Yes, make the `next` pointer point to the old list */
n->next = *l;
}
/* Make the list point to the new node */
*l = n;
}
这个函数可以这样调用:
/* Initialize to `NULL` to mark the list as empty */
struct node *list = NULL;
/* Add two nodes, passing the list pointer by reference */
add(&list, 12.34);
add(&list, 56.78);
该列表现在有两个节点:
- 列表中的第一个节点包含值
56.78
- 列表中的第二个节点包含值
12.34