我正在阅读一篇非常受欢迎的斯坦福文件*关于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
指针!
*:http://cslibrary.stanford.edu/103/LinkedListBasics.pdf,第5页和第6页
答案 0 :(得分:4)
但是头指针是在堆中分配的!
不完全是,指针指向的内存部分是堆中的内容。指针本身存储在函数堆栈中。
在图形中,堆栈空间中仅显示head
,但指针second
和third
也在堆栈中。这里的指针指的是保存地址的变量。这些变量指向的地址就是堆中的内容。
由于head->next
已分配给second
,因此您有两个指向同一事物的指针。依此类推third
。请注意,head->next
是存储在堆中的指针,并指向另一个堆内存地址。它与second
相同,它是存储在堆栈中的指针,其地址指向堆内存位置(同样,与head->next
相同)。因此,制作列表的另一种方法是仅分配第一个(head
)并使用其next
指针来直接分配存储地址的以下元素。与使用的(与直接指向第二和第三个元素)相比的缺点是你丢失了这个直接地址。您需要访问第一个和第二个才能找到第三个地址。
答案 1 :(得分:1)
它将头指针存储在"本地堆栈变量"中。但那 头指针在堆中分配!
每个节点都包含数据部分和指针部分。以上是说head的指针部分将指向第一个节点(位于堆中)。但是,头指针变量本身位于堆栈中。
头部指针的目的只是跟踪第一个节点,也可以用来通过它所拥有的地址来访问它。