C 程式的記憶體布局

2021-09-27 15:55:23 字數 1319 閱讀 4032

乙個c/c++源程式經過編譯之後,其應用程式使用的記憶體可劃分為一下幾個部分:

1)**區

**區存放函式體的二進位制**。可執行檔案載入之後,就存放在程序的**區。這部分分區域是唯讀的,如果試圖修改,將導致執行時錯誤。一般來說,程式的**區存放的是程式的可執行**,在某些特殊情況下,一些重要的資料也可以放入**區,以防止錯誤修改。

2)棧區

程式中用來存放函式的引數值、區域性變數、臨時變數。由編譯器生成的**自動完成記憶體的分配與釋放,操作類似於資料結構中的棧。windows下,棧是一塊由高位址向低位址方向生長的空間。在程式執行時,只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常,提示棧溢位。除非特別指定,c++程式執行時,棧的最大容量是系統預先規定好的。

#include"pch.h"

#include#includeusing namespace std;

int *addr;

int cnt;

//每次呼叫函式時,會把引數先壓棧,所以使用 addr-&i 就可以知道一次遞迴呼叫耗費多少記憶體

void func(int i)

int main()

執行結果:

記憶體溢位

所以乙個程序可以使用的記憶體大小大概是:4756*216/1024 = 1003k,大約1m。

3)堆區

供程式設計師動態申請和釋放空間的記憶體區。這個區域由程式設計師自己負責維護。

堆的具體實現和管理方式與作業系統相關,不同作業系統的實現細節是不同的。一般原理:在作業系統中設定乙個記錄空閒記憶體位址的鍊錶,當系統收到程式的申請時,遍歷該鍊錶,尋找第乙個空間大於申請空間的堆節點。然後將該節點從空閒節點鍊錶中刪除,並將該節點的空間分配給程式。而且一般會在這塊記憶體空間中的首位址處記錄本次分配的大小,以便**中的delete語句能夠正確地釋放本記憶體空間。由於找到的堆節點大小不一定等於申請的大小,系統會自動地將多餘的那部分重新放入空閒鍊錶中。

4)全域性/靜態區

用來存放全域性變數和靜態變數的記憶體區。程式在建立這塊儲存區時會自動將所有位元組清0.所以如果沒有顯示地位全域性(靜態)變數賦初始值,那麼它的初始值就是0.程式結束之後由系統釋放。

5)常量區

用於存放字串常量的記憶體區。程式執行結束後由系統自動釋放。

常量區既不是存放文字常量(存放在**區),也不是存放常變數(存放在棧區或堆區)的儲存區。常量區里存放的是字串常量,以及一些在程式執行中不能修改的重要資料(比如類的虛函式表等)。常量區是唯讀的,如果試圖修改,將導致執行時錯誤。

c 程式的記憶體布局

對任何乙個普通c 程式來講,它都會涉及到 5種不同的資料段。常用的幾個資料段種包含有 程式 段 程式資料段 程式堆疊段 等。不錯,這幾種資料段都在其中,但除了以上幾種資料段之外,程序還另外包含兩種資料段。下面我們來簡單歸納一下程序對應的記憶體空間中所包含的 5種不同的資料區。段 段是用來存放可執行檔...

C程式的記憶體布局

c程式的記憶體布局 c程式的典型記憶體表示由以下部分組成 1.文字段 cpu 執行的機器指令 2.初始化資料段 資料段 3.未初始化的資料段 也稱bss段 4.棧 自動變數以及每次函式呼叫時所需儲存的的資訊都放在棧中 5.堆 通常在堆中進行動態儲存分配 如下圖所示 測試 include includ...

C程式的記憶體布局

乙個c程式一直以來都是由以下5個段 pieces 組成 正文段。這是由cpu執行的機器指令部分。通常,正文段是可共享的,所以即使執行的程式 如文字編輯程式 c編譯程式 shell等 在儲存器中也只需有乙個副本 否則會造成資源浪費,試想如果開同樣的程式100個,每個正文段都要乙個相同副本 另外,正文段...