c語言記憶體布局

2021-09-13 18:07:14 字數 2424 閱讀 6289

在linux系統下乙個c語言程序的記憶體布局

寫c程式時,我們經常會列印乙個指標位址,說這個指標指向某某記憶體位址.可這些位址是真實物理記憶體位址嗎?不是!這些只是虛擬記憶體位址.

當乙個c程式調入記憶體開始執行後,在記憶體中就會產生乙個程序.而在多工作業系統中每個程序都擁有一片屬於自己的記憶體空間(記憶體沙盤),這個沙盤就是虛擬位址空間,在32位下是乙個4gb的大小的位址塊,這些虛擬位址通過頁表對映到物理記憶體.

但系統並不會真的一下分配給每乙個程序4gb的物理記憶體空間的對映= =(不現實啊),這4gb只能是說邏輯位址,它會隨著程序的真實需要自動擴充套件對映到物理記憶體空間,最大到4gb.

4gb(位址0-0xffffffff)其中1gb必須保留給系統核心(這是linux平台下),也就是說程序自身只能擁有3gb的位址(0-0xc0000000),如圖

**區:程式(函式)**所在,由編譯而得到的二進位制**被載入至此.**區是唯讀的!有執行許可權.**區一般都從0x08048000位址開始(linux下).值得注意的是,字串字面值(如」hello world」)就儲存在這個區.

資料段和bss段:合稱靜態區(全域性區),用來儲存靜態(全域性)變數.區別是 前者(資料段)儲存的是已初始化的靜態(全域性)變數,可讀寫.

後者(bss段)儲存的是未初始化的靜態(全域性)變數,可讀寫.

堆:自由儲存區.不像全域性變數和區域性變數的生命週期被嚴格定義,堆區的記憶體分配和釋放是由程式設計師所控制的.申請方式:c中是malloc函式,c++中是new識別符號.

棧:由系統自動分配和釋放.儲存區域性(自動)變數. 一般說的堆疊,其實是指 棧!

另外,值得注意的是,堆是由低位址向高位址分配空間;棧卻是由高位址向低位址分配空間.

下面這段**進一步說明c程式中各資料的記憶體布局:

123

4567

891011

1213

1415

1617

1819

2021

2223

2425

2627

2829

3031

3233

#include 

#include

int i1 = 10; //靜態全域性區(data段)

int i2; //靜態全域性區(bss段)

static int i3 = 30; //靜態全域性區(data段)

const int i4 = 40; //**區!!!

void fun(int i5) //棧區

int main(void)

程式輸出:

至此,從位址大小比較可以看出

1)靜態(static)全域性變數 和 靜態(static)區域性變數 都在 靜態全域性區.

2)全域性常量i4儲存在**區,而區域性常量i8儲存在棧區.

所以最上面的問題是,**區唯讀,修改全域性常量會引發執行時段錯誤,而區域性常量是可以成功賦值修改的.

3)字串字面值在**區(所以不可修改),但是字元指標str1在棧區;字元陣列str2在棧區(所以可以修改).

無論是堆還是棧,都要防止越界現象的發生。

static 全域性變數與普通的全域性變數有什麼區別 ?

全域性變數(外部變數)的定義之前再冠以 static 就構成了靜態的全域性變數。

全域性變數本身就是靜態儲存方式, 靜態全域性變數當然也是靜態儲存方式。 這兩者在儲存方式上並無不同。

這兩者的區別在於非靜態全域性變數的作用域是整個源程式, 當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。 而靜態全域性變數則限制了其作用域, 即只在定義該變數的原始檔內有效, 在同一源程式的其它原始檔中不能使用它。

由於靜態全域性變數的作用域侷限於乙個原始檔內,只能為該原始檔內的函式公用,因此可以避免在其它原始檔中引起錯誤。

static 全域性變數只初使化一次,防止在其他檔案單元中被引用。

static 區域性變數和普通區域性變數有什麼區別 ?

把區域性變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域性變數改變為靜態變數後是改變了它的作用域,限制了它的使用範圍。

static 區域性變數只被初始化一次,下一次依據上一次結果值。

static 函式與普通函式有什麼區別?

static 函式與普通函式作用域不同,僅在本檔案。只在當前原始檔中使用的函式應該說明為內部函式(static),內部函式應該在當前原始檔中說明和定義。對於可在當前原始檔以外使用的函式,應該在乙個標頭檔案中說明,要使用這些函式的原始檔要包含這個標頭檔案.static 函式在記憶體中只有乙份(.data),普通函式在每個被呼叫中維持乙份拷貝。

C語言記憶體布局

重點關注以下內容 c語言程式在記憶體中各個段的組成 c語言程式連線過程中的特性和常見錯誤 c語言程式的執行方式 一 c語言程式的儲存區域 由c語言 文字檔案 形成可執行程式 二進位制檔案 需要經過編譯 彙編 連線三個階段。編譯過程把c語言文字檔案生成匯程式設計序,彙編過程把匯程式設計序形成二進位制機...

c語言記憶體布局

在linux系統下乙個c語言程序的記憶體布局 寫c程式時,我們經常會列印乙個指標位址,說這個指標指向某某記憶體位址.可這些位址是真實物理記憶體位址嗎?不是 這些只是虛擬記憶體位址.當乙個c程式調入記憶體開始執行後,在記憶體中就會產生乙個程序.而在多工作業系統中每個程序都擁有一片屬於自己的記憶體空間 ...

C語言的記憶體布局

乙個典型c程式的的記憶體表達包括如下部分 1.文字段 2.初始化資料段 3.未初始化資料段 4.棧區 5.堆區 乙個執行程序的典型的記憶體布局 1.文字段 乙個文字段,也被稱作 段或者簡稱為文字,是乙個程式在物件檔案或者在記憶體中的其中一部分,包含可執行的指令。在記憶體區,文字段可能放在堆區或者棧區...