为了学习,我正在编写一个简单的链表实现。我的链表包含node
结构,其中包含int
值和指向下一个节点的指针。当我运行我的代码时,它会无休止地循环,即使它应该在到达NULL指针时终止。我做错了什么?
#include <stdio.h>
struct node {
int value;
struct node *next_node;
};
struct node * add_node(struct node *parent, int value)
{
struct node child;
child.value = value;
child.next_node = NULL;
parent->next_node = &child;
return parent->next_node;
}
void print_all(struct node *root)
{
struct node *current = root;
while (current != NULL) {
printf("%d\n", current->value);
sleep(1);
current = current->next_node;
}
}
int main()
{
struct node root;
root.value = 3;
struct node *one;
one = add_node(&root, 5);
print_all(&root);
}
答案 0 :(得分:5)
您的程序显示未定义的行为:您在此处设置指向本地分配的struct
的指针:
struct node child;
child.value = value;
child.next_node = NULL;
parent->next_node = &child;
return parent->next_node;
由于child
位于堆栈上,因此返回指向它的父级会导致未定义的行为。
您需要动态分配child
才能使其正常工作:
struct node *pchild = malloc(sizeof(struct node));
// In production code you check malloc result here...
pchild->value = value;
pchild->next_node = NULL;
parent->next_node = pchild;
return parent->next_node;
现在你已经动态分配了内存,不要忘记在链表的每个动态分配的节点上调用free
以防止内存泄漏。
答案 1 :(得分:4)
add_node
返回一个指向局部变量的指针,该局部变量立即超出范围,可以被其他函数重用。尝试在print_all
中访问此操作会导致未定义的行为。在您的情况下,地址会被current
指针重复使用,root->next_node
指向root
。
要解决此问题,您应该在add_node
struct node * add_node(struct node *parent, int value)
{
struct node* child = malloc(sizeof(*child));
if (child == NULL) {
return NULL;
}
child->value = value;
child->next_node = NULL;
parent->next_node = child;
return child;
}
由于这会动态分配内存,因此您需要稍后调用free
。切记不要试图释放root
,除非您将其更改为使用malloc
进行分配。