C中的堆栈变量混淆

时间:2017-01-30 22:10:56

标签: c

我正在阅读一篇非常受欢迎的斯坦福文件*关于C中的链接列表。 它有一个简单的功能,可以构建一个包含三个成员的简单LL。我唯一得到的并且我感到困惑的是它说它将head指针存储在"本地堆栈变量"中。但是head指针在堆中分配!请查看代码并帮助我理解它为什么是本地堆栈变量?

/*
 Build the list {1, 2, 3} in the heap and store
 its head pointer in a local stack variable.
 Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {

struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;

head = malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));

head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;

// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}

该文件提供了关于链接列表在内存中的外观的下图。我不知道为什么在堆栈区域绘制head指针!

enter image description here

*:http://cslibrary.stanford.edu/103/LinkedListBasics.pdf,第5页和第6页

2 个答案:

答案 0 :(得分:4)

  

但是头指针是在堆中分配的!

不完全是,指针指向的内存部分是堆中的内容。指针本身存储在函数堆栈中。

在图形中,堆栈空间中仅显示head,但指针secondthird也在堆栈中。这里的指针指的是保存地址的变量。这些变量指向的地址就是堆中的内容。

由于head->next已分配给second,因此您有两个指向同一事物的指针。依此类推third。请注意,head->next是存储在堆中的指针,并指向另一个堆内存地址。它与second相同,它是存储在堆栈中的指针,其地址指向堆内存位置(同样,与head->next相同)。因此,制作列表的另一种方法是仅分配第一个(head)并使用其next指针来直接分配存储地址的以下元素。与使用的(与直接指向第二和第三个元素)相比的缺点是你丢失了这个直接地址。您需要访问第一个和第二个才能找到第三个地址。

答案 1 :(得分:1)

  

它将头指针存储在"本地堆栈变量"中。但那   头指针在堆中分配!

每个节点都包含数据部分和指针部分。以上是说head的指针部分将指向第一个节点(位于堆中)。但是,头指针变量本身位于堆栈中。

头部指针的目的只是跟踪第一个节点,也可以用来通过它所拥有的地址来访问它。