C語言的記憶體管理

2022-03-16 09:35:02 字數 1683 閱讀 9540

**:

對於乙個c語言程式而言,記憶體空間主要由五個部分組成**段(.text)、資料段(.data)、bss段(.bss),堆(heap)和棧(stack)組成,其中**段,資料段和bss段是編譯的時候由編譯器分配的,而堆和

棧是程式執行的時候由系統分配的。布局如下:

bss段:bss段(block started by symbol)通常是指用來存放程式中未初始化(程式設計師在建立時沒有賦值)的全域性變數和靜態變數的一塊記憶體區域(可讀可寫不可執行)。特點是可讀寫的,在程式執行之前bss段會自動清0。 (注意:一般的書上都會說全域性變數和靜態變數是會自動初始化的,為什麼會這樣呢?變數的初始化可以分為顯示初始化(程式設計師在建立時手動賦值)和隱式初始化(程式設計師在建立時沒有賦值,編譯器自動將其初始化為0)。既然程式設計師未賦值的全域性變數和靜態變數最後都被自動賦值為0,那麼就沒必要把每個0都儲存起來,把這些未初始化的變數統一存在bss段,程式執行前統一將bss段清0即可。這樣做可以節省磁碟空間,同樣乙個程式如果全域性變數和靜態變數在建立時未初始化,那麼編譯器將其轉化成的二進位制可執行檔案就會小很多。這是bss的主要作用)。

資料段:資料段(data segment)通常是指用來存放程式中已初始化的全域性變數和靜態變數、字元常量的一塊記憶體區域(可讀可寫不可執行)。資料段屬於靜態記憶體分配,可以分為唯讀資料段和讀寫資料段。 字串常量等,但一般都是放在唯讀資料段中。

**段:**段(code segment/text segment)通常是指用來存放程式執行**的一塊記憶體區域(可讀可執行不可寫)。這部分區域的大小在程式執行前就已經確定,並且記憶體區域通常屬於唯讀, 某些架構也允許**段為可寫,即允許修改程式。在**段中,也有可能包含一些唯讀的常數變數,例如字串常量等,但一般都是放在唯讀資料段中。 

以上bss、資料段、**段都是編譯器在程式執行前就分配好的。如果**中的全域性變數和靜態變數在建立時不立即初始化,那麼它們會被儲存在bss段,bss段會在程式執行前統一清0,這樣程式的可執行檔案就會小很多。

下面兩個堆和棧是在程式執行時,動態分配的,不是由編譯器管理。

堆(heap):堆是用於存放程序執行中被動態分配的記憶體段(即物件),它的大小並不固定,可動態擴張或縮減(可讀可寫可執行)。當程序呼叫malloc等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張);當利用free等函式釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減) 

棧(stack):棧又稱堆疊, 是使用者存放程式臨時建立的區域性變數(可讀可寫可執行),也就是說我們函式括弧「{}」中定義的變數(但不包括static宣告的變數,static意味著在資料段中存放變數)。除此以外,在函式被呼叫時,其引數也會被壓入發起呼叫的程序棧中,並且待到呼叫結束後,函式的返回值也會被存放回棧中。由於棧的先進先出特點,所以棧特別方便用來儲存/恢復呼叫現場。從這個意義上講,我們可以把堆疊看成乙個寄存、交換臨時資料的記憶體區。注意:棧空間是向下增長的,每個執行緒有乙個自己的棧,在linux上預設的大小是8m(ios上線程預設是1m),可以用ulimit檢視和修改。

棧系統提供的功能,特點是快速高效,缺點是有限制,資料不靈活;而堆是函式庫提供的功能,特點是靈活方便,資料適應面廣泛,但是效率有一定降低。

note: 一般編譯器和作業系統實現來說,對於虛擬位址空間的最低(從0開始的幾k)的一段空間是未被對映的,也就是說它在程序空間中,但沒有賦予實體地址,不能被訪問。這也就是對空指標的訪問會導致crash的原因,因為空指標的位址是0。至於為什麼預留的不是乙個位元組而是幾k,是因為記憶體是分頁的,至少要一頁;另外幾k的空間還可以用來捕捉使用空指標的情況。

C語言的記憶體管理

對於乙個c語言程式而言,記憶體空間主要由五個部分組成 段 text 資料段 data bss段 bss 堆和棧組成,其中 段,資料段和bss段是編譯的時候由編譯器分配的,而堆和 在上圖中,由編譯器分配的位址空間都是在連線的時候分配的,而執行時分配的空間是在程式執行時由系統分配的 bss段 bss段 ...

C語言的記憶體管理

對於乙個c語言程式而言,記憶體空間主要由五個部分組成 段 text 資料段 data bss段 bss 堆和棧組成,其中 段,資料段和bss段是編譯的時候由編譯器分配的,而堆和 在上圖中,由編譯器分配的位址空間都是在連線的時候分配的,而執行時分配的空間是在程式執行時由系統分配的 bss段 bss段 ...

c語言的記憶體管理

對於乙個c語言程式而言,記憶體空間主要由五個部分組成 段 text 資料段 data bss段 bss 堆和棧組成,其中 段,資料段和bss段是編譯的時候由編譯器分配的,而堆和 棧是程式執行的時候由系統分配的。布局如下 在上圖中,由編譯器分配的位址空間都是在連線的時候分配的,而執行時分配的空間是在程...