C語言程序的記憶體分割槽 變數作用域和生存期

2021-08-24 18:17:11 字數 2203 閱讀 9216

c源**進過預處理、編譯、彙編和鏈結4步生成乙個可執行程式。

程式在沒有執行之前,也就是說程式沒有被載入到記憶體前,可執行程式內部已經分好3段資訊,分別是**區(text)、資料區(data)和未初始化資料區(bss)三個部分。(部分人直接把data和bss合起來叫做靜態區或全域性區)。 

執行可執行程式,系統把程式載入到記憶體,除了根據可執行程式的資訊分出**區、資料區和未初始化資料區之外,還額外增加了棧區和堆區。

**區存放cpu執行的機器指令。通常**區是可共享的(即另外的執行程式可以呼叫它),因為對於頻繁被執行的程式,只需要在記憶體中有乙份**即可。**區通常是唯讀的,為了防止程式意外地修改了它的指令。

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

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

棧是一種先進後出的記憶體結構,由編譯器自動分配釋放,存放函式的引數值、返回值、區域性變數等。在程式執行中實時載入和釋放,因此,區域性變數的生存週期為申請到釋放該段棧空間。不同的作業系統分配給每乙個程式的棧區大小不同:一般windows是1m ~ 8m不等,一般linux是1m ~ 16m不等。

1) 所有未初始化的靜態變數和全域性變數,編譯器會預設賦初值0.

2)程式在載入到記憶體前,**區和全域性區(data和bss)的大小就是固定的,程式執行期間不能改變。

3)data段和bss區中的資料的生存週期為整個程式執行過程。

4)data段、text區和bss區是由編譯器在編譯時分配的,堆和棧是由系統在執行時分配的。

a.普通區域性變數

屬於某個{},在{}外部不能使用此變數,在{}內部是可以使用。執行到普通區域性變數定義語句,才會分配空間,離開{},自動釋放普通區域性變數不初始化,預設值為隨機數。

b.static區域性變數

屬於某個{},在{}外部不能使用此變數,在{}內部是可以使用。在編譯階段就已經分配空間,離開{},static區域性變數不會釋放,只有整個程式結束才釋放。初始化只能使用常量。static區域性變數不初始化,預設值為0。

注意:靜態區域性變數的作用域屬於某個{},但是它的生命週期卻是從編譯階段到整個程式結束。

c.普通全域性變數

普通全域性變數只要定義了,任何地方都能使用,使用前需要宣告所有的.c檔案,只能定義一次普通全域性變數,但是可以宣告多次(外部鏈結)。在編譯階段分配空間,只有整個程式結束才釋放。。

注意:全域性變數的作用域是全域性範圍,但是在某個檔案中使用時,必須先宣告。

d.static全域性變數

static全域性變數只能在定義所在的檔案中使用此變數(內部鏈結)。在編譯階段分配空間,只有整個程式結束才釋放。不同的.c檔案,可以定義一次static全域性變數。

e.extern函式和static函式的區別(作用域)

extern函式所有檔案都可以呼叫,所有檔案中只能定義一次extern函式。

static函式只能在定義所在的檔案中呼叫此函式,不同檔案,可以定義一次static函式。

C語言記憶體分割槽,變數的作用域和生存週期

記憶體分為棧區 stack 堆區 heap 全域性區 靜態區 data區 區 text segment 四個區。而每乙個記憶體分割槽,又起著不同的作用。區 text segment 載入的是可執行檔案 段,所有的可執行 都載入到 區,這塊記憶體是不可以在執行期間修改的。作用域 就是變數的範圍 生命週...

C 作用域 記憶體分割槽的彙總

1.1 auto 自動變數 一般情況下 塊內部定義的變數都是自動變數 棧變數 當然也可以顯示的使用auto關鍵字。1.2 register 暫存器變數 register int i 把變數放到 cpu的暫存器裡面 執行效率會更高,但取不到變數的位址 i會出錯 1.3 extern 關鍵字 exter...

C語言變數作用域

作用域描述程式中可訪問識別符號的區域。乙個c變數的作用域可以是塊作用域,函式作用域,函式原型作用域或檔案作用域。int fun int a q作用域結束 在這個例子中,q的作用域只在內層塊,只有內層塊中的 才能訪問q。在c99中,把塊的概念擴充套件到for迴圈,while迴圈,do while迴圈和...