程式位址空間

2021-10-04 05:06:08 字數 1735 閱讀 2310

上圖也可以進一步細分:

1.棧區:棧又叫堆疊,通常存放程式臨時建立的非靜態區域性變數(即函式大括號中定義的區域性變數)以及函式呼叫時的引數,呼叫後的返回值等。由編譯器自動分配釋放。棧是向下增長的。

棧具有「小記憶體、自動化、可能會溢位」的特點。棧頂的位址和棧的最大容量一般是系統預先規定好的,通常不會太大。由於棧中主要存放的是區域性變數,而區域性變數的占用的記憶體空間是其所在的**段或函式段結束時由系統**重新利用,所以棧的空間是迴圈利用自動管理的,一般不需要人為操作。如果某次區域性變數申請的空間超過棧的剩餘空間時就有可能出現 「棧的溢位」,進而導致意想不到的後果。所以一般不宜在棧中申請過大的空間,比如長度很大的陣列、遞迴呼叫重複次數很多的函式等等。

2.堆區:通常存放程式執行中動態分配的儲存空間。它的大小,並不固定,可動態擴張或縮放。當程序呼叫malloc/free等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張),釋放的記憶體從堆中被提出(堆被縮減)。堆與資料結構中的堆是兩回事,分配方式類似於鍊錶。堆是向上增長的。

堆具有「大記憶體、手工分配管理、申請大小隨意、可能會洩露」的特點,堆記憶體是作業系統劃分給堆管理器來管理的,管理器向使用者(使用者程序)提供api(malloc和free等)來使用堆記憶體。需要程式設計師手動分配釋放,如果程式設計師在使用完申請後的堆記憶體卻沒有及時把它釋放掉,那麼這塊記憶體就丟失了(程序自身認為該記憶體沒被使用,但是在堆記憶體記錄中該記憶體仍然屬於這個程序,所以當需要分配空間時又會重新去申請新的記憶體而不是重複利用這塊記憶體),就是我們常說的-記憶體洩漏,所以記憶體洩漏指的是堆記憶體被洩露了。

3.靜態區(全域性資料區)(static):全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域(資料區),未初始化的全域性變數和靜態變數在相鄰的另一塊區域(bss區)。另外文字常量區,常量字串就是放在這裡,程式結束後由系統釋放。

資料區(全域性初始化資料區 data):該區包含了在程式中明確被初始化的全域性變數、靜態變數(包括全域性靜態變數和區域性靜態變數)。

bss區(未初始化資料區):存入的是全域性未初始化變數。bss這個叫法是根據乙個早期的彙編運算子而來,這個彙編運算子標誌著乙個塊的開始。bss區的資料在程式開始執行之前被核心初始化為0或者空指標(null)。llinux環境下可以用size命令 檢視c程式的儲存空間布局,可以看出,此可執行程式在儲存時(沒有調入到記憶體)分為**區(text)、資料區(data)和未初始化資料區(bss)3個部分。

乙個正在執行著的c編譯程式占用的記憶體分為**區、初始化資料區、未初始化資料區、堆區和棧區5個部分。

4.**區(text):用來存放cpu執行的機器指令,也有可能包含一些唯讀的常數變數,例如字串常量等。通常,**區是可共享的(即另外的執行程式可以呼叫它),因為對於頻繁被執行的程式,只需要在記憶體中有乙份**即可。這部分區域的大小在程式執行之前就已經確定,通常是唯讀的,使其唯讀的原因是防止程式意外地修改了它的指令。另外,**區還規劃了區域性變數的相關資訊。

常量區其實是一塊不同於**區的區域,但是因為常量和**一樣具有唯讀性質,所以有時候說**段是包含了常量區的。

5、共享區:用來裝載乙個共享的動態記憶體庫;使用者還可以使用系統介面建立共享記憶體,做程序間通訊。

程式位址空間

乙個全域性變數,在子程序中修改後,列印100,父程序還是列印1 資料不同,表示肯定沒有使用同一塊記憶體空間 一塊記憶體空間不能儲存兩個資料 父子程序列印的資料不同,但是位址卻是相同的 此處產生矛盾,因為實際程序中訪問的位址都是虛擬位址,且程式位址空間時機上也是乙個程序的虛擬位址空間。size 表示記...

c程式位址空間

我們都知道指標在計算機中占有很重要的部分,但指標究竟是什麼呢?有人說 指標就是位址,因為指標都是指向乙個位址空間的,這麼說也沒毛病,但不準確。例如 int a 10 int p a 很顯然指標變數p中所存的是 a,不過這只是指標變數的一部分,是指標變數作為左值的表現,還有指標變數作為右值的呢,那麼p...

Linux 程式位址空間

我們所說的位址是乙個虛擬的位址空間,只是一堆位址編號的描述,非物理記憶體位址 虛擬位址不具備儲存能力,資料儲存依然放到物理記憶體中 程序中訪問的位址都是虛擬位址,非物理記憶體位址 程式位址空間也是乙個虛擬位址空間,是作業系統為程序通過乙個mm struct 結構體所描述的乙個假的位址空間 mm st...