2017-01-30 73 views
1

我在C. 讀一本非常流行的斯坦福文檔*有關鏈表這裏面一個簡單的函數,建立具有三個成員的簡單LL。我沒有得到的唯一的東西,我感到困惑的是,它說它將head指針存儲在「本地堆棧變量」中。但是,head指針被分配在堆中!請看看代碼,並幫助我理解爲什麼它是一個本地堆棧變量?堆棧變量混淆使用C

/* 
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

+5

你在混淆「頭部指針」和「頭部指針指向的東西」。 – immibis

+0

請您詳細說明一下嗎?代碼是說'頭'指針是本地的功能。哪個局部變量?所有變量('head','second'和'third')堆在一起 –

+3

這個頭指針**變量**,*就像那個函數中的所有其他變量*一樣,都是自動的(在你的白話中,它們活着這個想法就是這樣,在範圍退出時,變量'head'到期並且不再存在,因此它的值被丟失了。那麼,如果你做了*會不會將'head'中的值作爲函數結果返回給調用者,然後調用者將其存儲起來?除非有其他人保留這個值(就像你通過'返回'給調用者那樣),否則它永遠丟失了,並且有了它,任何機會都可以「讓」你的鏈表的初始節點。 – WhozCraig

回答

4

但是,這頭指針在堆中分配!

不完全是,指針指向的內存部分是堆中的內容。指針本身存儲在你的函數堆棧中。

在圖中,堆棧空間中只顯示head,但指針secondthird也位於堆棧中。這裏指的是指向包含地址的變量的指針。這些變量指向的地址就是堆中的內容。

由於head->next被分配到second,你有兩個指針指向同一件事。和third一樣。請注意,head->next是一個存儲在堆中的指針,並指向另一個堆內存地址。它與second相同,它是一個存儲在堆棧中的指針,其地址指向堆內存位置(同樣與head->next相同)。因此,另一種列表的方式是隻分配第一個(head)並使用它的next指針直接分配存儲地址的以下元素。與使用什麼(與直接指向第二和第三個元素的指針)相比,它的缺點是你失去了這個直接地址。您需要訪問第一個和第二個以查找第三個地址。

1

它被存儲在「局部變量堆棧」的頭指針。但是這個 頭指針是在堆中分配的!

每個節點包含一個數據部分和指針部分。上面說的是頭的指針部分將指向第一個節點(位於堆中)。但是,頭指針變量本身位於堆棧中。

頭指針的目的只是爲了保持跟蹤的第一個節點,並且還可以通過使用其持有它的地址來訪問它。