c c 程式的記憶體分割槽模型詳解

2021-10-01 03:47:29 字數 2211 閱讀 2106

我們要想執行我們編寫的c程式,那麼第一步需要對這個程式進行編譯。

預處理:巨集定義展開、標頭檔案展開、條件編譯,這裡並不會檢查語法

編譯:檢查語法,將預處理後檔案編譯生成彙編檔案

彙編:將彙編檔案生成目標檔案(二進位制檔案)

在沒有執行程式前,也就是說程式沒有載入到

記憶體前,可執行程式內部已經分好3段資訊,分別為**區(text)、資料區(data)和未初始化資料區(bss)3 個部分(有些人直接把data和bss合起來叫做靜態區或全域性區)

存放 cpu 執行的機器指令。通常**區是可共享的(即另外的執行程式可以呼叫它),使其可共享的目的是對於頻繁被執行的程式,只需要在記憶體中有乙份**即可。

**區通常是唯讀的

,使其唯讀的原因是防止程式意外地修改了它的指令。另外,**區還規劃了區域性變數的相關資訊。

該區包含了在程式中明確被初始化的全域性變數、已經初始化的靜態變數(包括全域性靜態變數和區域性靜態變數)和常量資料(如字串常量)。

存入的是全域性未初始化變數和未初始化靜態變數。未初始化資料區的資料在程式開始執行之前被核心初始化為 0 或者空(null)。

總體來講說,程式源**被編譯之後主要分成兩種段:程式指令和程式資料。**段屬於程式指令,而資料域段和.bss段屬於程式資料。

那為什麼把程式的指令和程式資料分開呢?

程式在載入到記憶體前,**區和全域性區

(data

和bss)

的大小就是固定的,程式執行期間不能改變。然後,執行可執行程式,作業系統把物理硬碟程式load(載入)到記憶體,除了根據可執行程式的資訊分出**區(text)、資料區(data)和未初始化資料區(bss)之外,還額外增加了棧區、堆區。

載入的是可執行檔案**段,所有的可執行**都載入到**區,這塊記憶體是不可以在執行期間修改的。

載入的是可執行檔案bss段,位置可以分開亦可以緊靠資料段,儲存於資料段的資料(全域性未初始化,靜態未初始化資料)的生存週期為整個程式執行過程。

載入的是可執行檔案資料段,儲存於資料段(全域性初始化,靜態初始化資料,文字常量

(唯讀)

)的資料的生存週期為整個程式執行過程。

棧是一種先進後出的記憶體結構,由編譯器自動分配釋放,存放函式的引數值、返回值、區域性變數等。在程式執行過程中實時載入和釋放,因此,區域性變數的生存週期為申請到釋放該段棧空間。

堆是乙個大容器,它的容量要遠遠大於棧,但沒有棧那樣先進後出的順序。用於動態記憶體分配。堆在記憶體中位於bss區和棧區之間。一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時由作業系統**。

型別

作用域

生命週期

儲存位置

auto變數

一對{}內

當前函式 棧區

static

區域性變數

一對{}內

整個程式執行期

初始化在data段,未初始化在bss段

extern變數

整個程式

整個程式執行期

初始化在data段,未初始化在bss段

static

全域性變數

當前檔案

整個程式執行期

初始化在data段,未初始化在bss段

extern函式

整個程式

整個程式執行期

**區static函式

當前檔案

整個程式執行期

**區register變數

一對{}內

當前函式

執行時儲存在cpu暫存器

字串常量

當前檔案

整個程式執行期

data段

在理解c/c++記憶體分割槽時,常會碰到如下術語:資料區,堆,棧,靜態區,常量區,全域性區,字串常量區,文字常量區,**區等等,初學者被搞得雲裡霧裡。在這裡,嘗試捋清楚以上分割槽的關係。

資料區包括:堆,棧,全域性/靜態儲存區。

全域性/靜態儲存區包括:常量區,全域性區、靜態區。

常量區包括:字串常量區、常變數區。

**區:存放程式編譯後的二進位制**,不可定址區。

可以說,c/c++記憶體分割槽其實只有兩個,即**區和資料區。

C C 記憶體分割槽

堆區 由程式設計人員手動申請,手動釋放,若不手動釋放,程式結束後由系統 生命週期是整個程式執行期間。使用malloc或者new進行堆的申請,堆的總大小為機器的虛擬記憶體的大小。ps self view 由malloc申請的叫做堆區,new申請的叫做自由儲存區 棧區由系統進行記憶體的管理。主要存放函式...

c c 記憶體分割槽

主要用於儲存函式的引數和區域性變數。棧區由系統進行記憶體管理,在函式執行完成時,系統自動釋放棧區的記憶體,而不需要使用者的參與,整個程式的棧區的大小可以在編譯器中由使用者自行設定。由使用者手動申請,手動釋放。如果使用者忘記對所申請的記憶體資源進行釋放,該記憶體資源可能會在程式結束時由操 作系統進行釋...

C C 程式記憶體分配詳解

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 程式執行時由編譯器自動分配,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。程式結束時由編譯器自動釋放。2 堆區 heap 在記憶體開闢另一塊儲存區域。一般由程式設計師分配釋放,若程式設計師不釋放,程式結...