指针 - 对内存位置的不一致访问

时间:2017-09-29 19:02:29

标签: c pointers

我正在尝试定义一个简单的链接列表

#include <stdio.h>


struct node{
  int value;
  struct node* next;
};


typedef struct {
  struct node* root;
} ll;

void add_to_ll(int value, ll* linked_list) {
  struct node new_node = {value, linked_list->root};
  linked_list->root = &new_node;
}

void print_ll(ll* ll2) {
  printf("%p", ll2);
  struct node* temp = ll2->root;
  while (temp->next != NULL) {
    printf("%d ", temp->value);
    temp = temp->next;
  }
}


int main()
{
  printf("Creating a linked list...\n");
  struct node root_node = {1, NULL};
  ll my_linked_list = { &root_node };
  for (int i = 0; i < 10000; i++) {
    add_to_ll(i, &my_linked_list);
  }
  printf("my_linked_list root value %d\n", my_linked_list.root->value);
  printf("my_linked_list root value %d\n", my_linked_list.root->value);
  printf("my_linked_list root value %d\n", my_linked_list.root->value);
  return 0;
}

我得到的输出是:

Creating a linked list...
my_linked_list root value 9999
my_linked_list root value 429391991
my_linked_list root value 429391991

我第一次能够正确获取value节点的root。但是在尝试第二次(以及之后)读取它时,值会发生变化。我错过了什么?

2 个答案:

答案 0 :(得分:2)

您的问题在于添加内存分配策略。

void add_to_ll(int value, ll* linked_list) {
  struct node new_node = {value, linked_list->root};
  linked_list->root = &new_node;
}

这里你将new_node设置为局部变量。非静态局部变量的寿命等于其块的寿命。退出块后,该内存(实际上是堆栈)可用于连续分配,这将覆盖您的对象。使用显式分配,即malloc,使对象的生命周期独立于分配范围。

我还要指出命名...最明确的名称应该是类型的名称,而不是变量。所以struct linked_list ll而不是相反。

答案 1 :(得分:0)

此功能:

void add_to_ll(int value, ll* linked_list) {
  struct node new_node = {value, linked_list->root};
  linked_list->root = &new_node;
}

在堆栈上构造一个节点并将其添加到列表中。 当您从此函数返回时,将弹出堆栈,并且列表根指向堆栈上的未分配内存,稍后将重复使用。