天天看點

關于程式運作時函數的堆棧記憶體空間配置設定情況

關于程式運作時函數的堆棧記憶體空間配置設定情況

程式運作時主函數main和其他函數的記憶體空間是配置設定到同一個棧,每次程式開始運作時都會建立一個棧,main函數就在棧底,然後通過不同函數的調用順序,依次進棧出棧。堆是程式動态配置設定的空間,每次配置設定的空間不一定是連續的。

關于程式運作時函數的堆棧記憶體空間配置設定情況
  1. 關于棧記憶體配置設定,系統自動配置設定。在執行函數時,函數内局部變量的存儲單元都在棧上建立,函數執行結束時這些存儲單元自動被釋放。棧記憶體配置設定運算内置于處理器的指令集中,一般使用寄存器來存取,效率很高,但是配置設定的記憶體容量有限。
    關于程式運作時函數的堆棧記憶體空間配置設定情況
  2. 關于堆記憶體配置設定,亦稱動态記憶體配置設定,根據編寫的代碼配置設定。程式在運作的時候用malloc或new申請任意多少的記憶體,程式員自己負責在何時用free或delete來釋放記憶體。動态記憶體的生存期由程式員自己決定,使用非常靈活。
  3. 關于靜态存儲區記憶體配置設定,全局變量全部存儲在靜态存儲區中,在程式開始執行時給全局變量配置設定存儲區,程式執行完畢就釋放。在程式執行過程中它們占據固定的存儲單元,而不是動态的進行配置設定和釋放。

棧是機器系統提供的資料結構,計算機會在底層對棧提供支援:配置設定專門的寄存器存放棧的位址,壓棧出棧都有專門的指令執行。堆則是C函數庫提供的,它的機制很複雜,例如為了配置設定一塊記憶體,庫函數會按照一定的算法(具體的算法可以參考資料結構/作業系統)在堆記憶體中搜尋可用的足夠大的空間,如果沒有足夠大的空間(可能是由于記憶體碎片太多),就有需要作業系統來重新整理記憶體空間,這樣就有機會分到足夠大小的記憶體,然後傳回。顯然,堆的效率比棧要低得多。

最後,編譯器一般使用棧來存放函數的參數、局部變量等來實作函數調用。有時候函數有嵌套調用,這個時候棧中會有多個函數的資訊,每個函數占用一個連續的區域。一個函數占用的區域被稱作幀。同時棧是線程獨立的,每個線程都有自己的棧。一個線程隻有一個棧,這個線程中執行的所有函數都會用這個棧。函數被調用的時候會在棧頂開辟一部分空間(實質上隻是将棧頂上移)儲存自己的資料,這些資料就包括函數的參數、傳回位址、局部變量。函數傳回的時候隻要把棧頂回複到被調用前的狀态就把它占用的空間釋放了。

感謝閱讀~

繼續閱讀