2010-06-17 156 views
1

我已經搜索了一段時間,但沒有確定的答案是爲什麼值類型必須分配在棧上,而引用類型即動態內存或對象必須駐留堆。 爲什麼不能在堆棧上分配同樣的東西?爲什麼堆棧和堆都需要內存分配

回答

0

局部變量分配在堆棧中。如果情況並非如此,那麼在分配變量內存時,您將無法將變量指向堆。如果需要,您可以在堆棧中分配內容,只需在本地創建一個足夠大的緩衝區並自行管理它。

+0

所以基本上你正在堆棧上定製託管堆。 ;) – 2010-06-17 17:27:54

+0

@bjarkef - 嘿,一個人不得不做的事:) – 2010-06-17 17:28:21

3

他們可以。實際上,它們並不是因爲堆棧通常比堆堆稀少,並且在堆棧上分配引用類型可能會耗盡它們。此外,如果一個函數返回在其堆棧上分配的數據,它將需要在調用者的部分上覆制語義,否則有可能返回將被下一個函數調用覆蓋的內容。

通過本地機器指令,可以快速方便地將值類型(通常爲本地變量)引入和取消範圍。複製返回值類型的語義是微不足道的,因爲它最適合於機器寄存器。這經常發生,應該儘可能便宜。

1

我明白堆棧範式(嵌套的分配/釋放操作)不能處理這需要非嵌套的對象生命週期某些算法。

就像靜態分配範式無法處理遞歸過程調用。 (例如斐波納契(n)的天真計算爲f(n-1)+ f(n-2))

我不知道一個簡單的算法,可以說明這個事實。任何建議將不勝感激:-)

0

任何方法放入堆棧將消失方法退出時。在.net和Java中,如果一個類對象一旦最後一次引用消失,它就會完全被接受(實際上是可取的),但是當引用它仍然存在時,對象消失將是致命的。在一般情況下,編譯器無法知道方法創建對象時,在該方法退出後,對該對象的任何引用是否會繼續存在。如果沒有這種保證,分配類對象的唯一安全方法是將它們存儲在堆中。

順便說一下,在.net中,可變值類型的一個主要優點是它們可以通過引用傳遞,而不會放棄對它們的永久控制。如果類「foo」或其方法具有結構'boz',foo的方法之一通過引用方法'bar'傳遞,則bar或其調用的方法可能做任何他們想要的操作' boz'直到他們返回,但是一旦「bar」返回了它所持有的「boz」的引用將會消失。這通常會導致比用於類對象的可混合共享引用更安全和更乾淨的語義。