2013-07-25 182 views
-1

有人可以建議我使用任何練習或代碼來幫助我更好地理解堆棧和堆棧內存嗎?我已經在教科書中閱讀了很多,只是想看到一些代碼更好地理解。也許一些堆棧溢出的例子或類似的東西。我認爲C/C++將是一個理想的候選人。使用C/C++/Java程序理解堆棧和堆棧

回答

0

堆棧和堆都駐留在內存中。在哪裏並不一定重要,但你應該設法瞭解他們的數據結構。

堆:

對於你應該閱讀的mallocthis example implementation,它應該給你它是如何工作的想法堆(包括代碼)。

棧(理論):

堆棧(基本的數據結構)是一種相當簡單的概念來理解和解釋不夠好here。該鏈接還簡要介紹了它在程序中的使用方式。我還沒有發現的東西,我想說明它在一個不錯的方式,所以我會包括以下內容作爲附加參考跟進:

  1. 有一個關於它可用here
  2. 一個簡單的電源點有趣(而且相當參與)視頻here
  3. 和簡化解釋here

如果這些不太解釋是正確的,你應該嘗試找到一些解釋調用堆棧並在某種程度上你就會明白堆棧幀

棧(代碼):

我所指出的鏈接解釋的理論,不給你的代碼。在瞭解計算機體系結構和彙編語言後,我對堆棧的理解得到了顯着改善。

所以,如果你想要一個代碼示例你應該嘗試和實現一個簡單的彙編函數並將其鏈接到一個C程序。 Here is an example (with a brief intro into assembly)

Java和C++:

Java和C++隱藏你這個東西,所以如果這是一個學習的過程,我建議C和彙編。我不確定是否可以用Java來做到這一點。你可以在C++,但它變得複雜了......

我的調用堆棧的解釋:

我會嘗試給調用堆棧的一個簡短的說明和堆棧幀相對於C編程語言和大會。

要做到這一點,可以定義一個簡單的機器,以便我們可以在同一頁面上開始。

我們的處理器具有有限數量的寄存器,可以說8個。像加法,減法,比較等操作只能在寄存器上完成。只有兩條指令可以在內存上執行,它們是加載商店。這些指令分別從存儲器複製到寄存器或從寄存器複製到存儲器。

現在,如果我們想要添加2個數字,我們有很多變量。我們將一個數字加載到寄存器1中,另一個數字加載到寄存器2中,並將它們相加並將結果存入寄存器3.現在,如果我們對寄存器4和5執行另一個操作,則將結果存儲在寄存器6中,然後想要添加寄存器7和8我們在哪裏放置結果?我們已經用完了變量...

很明顯我們需要使用內存和保存信息,當我們不是處理它。要做到這一點,我們需要知道其中在每個變量的內存中。

您可以記住每個變量的地址,並且每次都手動輸入它們,可能會將其寫在桌子上一張紙上明智的名稱旁邊。但那將是乏味的,並且會對功能造成嚴重的限制。

函數有本地變量。如果這些變量的地址是硬連線的,那麼它們總是會被分配給,並且會對遞歸造成很大的問題。如果一個函數自己調用,它會覆蓋它調用者(本身)正在使用的值。

要解決這個問題,最簡單的方法是使用堆棧。但是,爲此,我們需要保持堆棧指針地址。所以讓我們同意,從現在起我們將使用寄存器8作爲我們的堆棧指針

也可以說,當你把東西到堆棧中,我們將減去我們從堆棧指針想要的字節數,當我們要彈出我們的字節數添加到堆棧指針

每次我們調用函數時,我們都會將其局部變量放在堆棧上。既然我們知道我們想要什麼變量,我們知道需要多少內存。

但要訪問每個本地變量我們需要知道它的地址...讓我們設置一個示例。

比方說,我們有2個變量,這兩者在我們的功能2個字節,堆棧指針爲18

根據我們的協議,允許用戶從堆棧指針減去4個字節,使得堆棧指針等於14.

現在要訪問第一個變量,我們將簡單地使用堆棧指針。要訪問第二個,我們將從堆棧指針中減去2。

只要我們的功能正在運行,這將是真實的,但在此之前我們的函數退出,我們將免費我們從堆棧中的局部變量再次將4它,使堆棧指針18(就像是我們前啓動)。