2012-09-05 45 views
2

據我的理解,每個線程通常只獲得一個堆棧(而一個進程中的所有線程通常共享一個堆)。我一直認爲堆棧用於存儲函數調用發生時程序計數器(PC)的值。但後來我在某處讀取某些變量類型,如integerboolean也被分配到堆棧中。由於堆棧上的值是以嚴格的FILO方式管理的,因此這些變量如何隨時檢索?變量如何在任何時候被檢索,如果他們被分配到堆棧上?

例如,在聲明int a, b, c;之後,我可以在任何時間範圍內隨時對這些變量進行任何操作。這是如何完成的?爲什麼值c在堆棧頂部,因此隱藏值a, b

回答

1

調用堆棧也用於局部變量,也用於將參數傳遞給函數。

你說得對:'值類型'被傳遞到棧上,而引用類型被分配在堆上,但是當一個引用類型被用作參數時,指向這個堆位置的指針仍然會被傳遞堆棧。

儘管堆棧通常被認爲是LIFO緩衝區,但也有與調用堆棧相關的幀或基本指針,可用於直接訪問當前堆棧指針之上或之下的內存。這就是函數如何在不改變堆棧指針的情況下仍然可以隨機訪問參數。

diagram from Wikipedia可能會幫助形象化這一點,但請注意,很多人會認爲堆棧應該「向下」增長。

本博客文章here解釋英特爾調用堆棧

1

首先我建議你應該研究一般多一點堆棧(見WikipediaStack Explanation等人通過谷歌搜索/ CS書籍)。

不過,對於您的具體問題,不堆產生的所有變量都在堆棧中。這通常包括您在特定函數中定義的任何不直接堆分配的內容(通過C++和Java中的new運算符)。在某些語言中,一切都是堆分配的,只有指向這些堆結構的指針纔會被存儲在堆棧中(就像在Python中一樣)。你會在語言之間看到各種各樣的細微變化。

因此,關於整數和布爾總是在堆棧上的陳述是不正確的。如果你在函數中定義它們,並且在堆中使用new來構建它們,則它們在堆棧中。需要注意的是與Java如果您使用的int原始它通常棧爲基礎和Integer對象是基於堆 - 但這是Java的更先進的細微差別超越了基本的棧知識。

可以將所有相同的範圍內訪問int a, b, c;,因爲它使空間可用於函數棧範圍內的所有3個變量。當函數返回時,這些變量在堆棧移回時被清除。在此之前,所有3個都存在,因爲整個範圍塊一次是堆棧的FILO結構的一部分,並會一直持續到您返回。

1

這個問題有很多答案,取決於你在什麼環境下工作。當然,你不應該把處理器棧等同於(用於機器代碼POP和PUSH)指令與棧(或更正確stackframe)被python解釋器或類似的東西所使用。淨運行

但簡短的回答是堆棧的頂部是一個簡單的存儲位置,所以您只需使用一個偏移

如果你沒有按A,B,C

所以B的地址將堆棧地址 - 4.

相關問題