链接列表无休止地循环

时间:2013-08-17 18:01:12

标签: c

为了学习,我正在编写一个简单的链表实现。我的链表包含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);
}

2 个答案:

答案 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进行分配。