2012-03-22 110 views
1

我正在學彙編,目前我們正在學習堆棧。從我學到的東西中,所有推入堆棧的東西最終都必須彈出(清理堆棧)。爲什麼我們絕對需要清理堆棧?我讀過它是爲了防止內存泄漏,是嗎?爲什麼我們必須清理堆棧

非常感謝您

回答

2

堆棧是內存量有限,而且與如果你從來沒有清理任何內存分配系統,它會簡單地成長和壯大。最終你會溢出堆棧,並且當你覆蓋其他內存區域或者簡單地生成無效地址時,所有地獄都會崩潰。

3

給定的執行線程只有一定數量的堆棧。

它的目的是暫時保存一個函數被調用時所需的數據(比如返回地址和傳遞給函數的參數)。

如果你這樣做而不是當你的函數退出時清理堆棧,你將最終用完堆棧空間。另外,作爲超越堆棧的一般規則,應該儘可能縮短程序使用的任何資源(堆棧空間,堆空間,文件句柄等)以提高整體效率。

2

如果你沒有清理堆棧,調用函數將如何找到它的變量?被調用者將運行,使用自己的變量在堆棧上執行一些操作,然後返回調用者 - 現在,如果堆棧指針發生更改,調用者可以做些什麼?它如何恢復它以找出它自己的堆棧變量在哪裏?唯一的答案是清理堆棧 - 不管它是誰(被調用者或調用者),但有人必須。

術語「內存泄漏」通常是指失去了指向一個動態內存分配,讓你不能free()該分配。

+0

「內存泄漏」通常是指丟失指針,因爲堆棧實際上總是被清除(編譯器強制執行)。如果它仍然由用戶來清理堆棧(就像使用程序集一樣),實際上也可能會泄漏堆棧內存,實際上我們會談到「堆棧內存泄漏」和「堆內存泄漏」。 – 2012-03-23 20:46:27

2

除了其他的答案,我使用的大多數處理器都將函數調用的返回地址放在堆棧上。

的RET/RTS(或任何回報,如果使用您的處理器語法)簡單地從堆棧中的返回地址,並設置PC,ProgramCounter,到該地址。

如果函數將在堆棧上額外的變量,但不刪除它們,則RET將會重新拉開大錯誤值,並且將返回的地址不正確造成的種種古怪行爲,或例外/陷阱。

故障引起的這種行爲會變得很難調試,特別是如果他們沒有過錯immediatley

1

軟件程序(函數)可以共享堆棧獲取調用的參數和返回變量以及記憶呼叫者的返回地址。

由於程序集中的堆棧指針通常是一個寄存器,它是一種全局變量。如果在函數結束時,堆棧指針沒有設置到合適的位置(「堆棧清理」),則會發生很多不好的事情。系統可能返回錯誤的地址,調用者可能彈出錯誤的返回值,可能會出現堆棧溢出,下溢等。

+0

@artjomb。在完成20個更改請求後,我很難找到那個鏈接中不那麼好的東西。我有一些明顯的拒絕,但有些是測試。你的元信息是否準確? – Fuhrmanator 2016-03-27 18:17:13

+0

@ArtjomB。感謝您的鏈接。我瞭解到代碼更改是不允許的(合理),並且語法改進是主觀的!復活節快樂。 – Fuhrmanator 2016-03-27 18:34:46

+0

記錄這個討論有什麼不對? – Fuhrmanator 2016-03-30 22:41:47

1

每個功能可能會使用堆棧,即使一些不你會得到的函數嵌套在程序中一個()調用調用兩個()兩個調用的三()等

所以,如果一個函數具有本地變量A,B,C在堆棧上,然後它調用兩個,兩個有兩個變量,它使用堆棧中的E和F.然後三個在堆疊上有G和H.如果你沒有將堆棧指針恢復到三個進入時的位置,當你返回到兩個時,它會認爲它正在訪問E和F,但將訪問G和H或其他的東西,這取決於三個堆棧幀()函數。

你不會得到內存泄漏,你會崩潰。有時候你很幸運並存活下來,這可能是這些函數代碼的本質,但總的來說,它會導致編譯後的代碼失敗。

現在它是內存泄漏從某種意義上說,一個功能是搗毀某人elm ram,當然。

對於使用堆棧作爲返回值的處理器,情況會變得更糟,崩潰或奇怪行爲會更有保證,更糟糕。

相關問題