在理解C/C++內存分區時,常會碰到如下術語:數據區,堆,棧,靜態存儲區,靜態區,常量區,常變量區,全局區,字符串常量區,靜態常量區,靜態變量區,文字常量區,代碼區等等,初學者被搞得云里霧里。在這里,嘗試捋清楚以上分區的關系。[1]
數據區包括:堆,棧,全局/靜態存儲區。
全局/靜態存儲區包括:常量區(靜態常量區),全局區(全局變量區)和靜態變量區(靜態區)。
常量區包括:字符串常量區和常變量區。
代碼區:存放程序編譯后的二進制代碼,不可尋址區。
可以說,C/C++內存分區其實只有兩個,即代碼區和數據區。
一、真正合理的C++的內存劃分為棧區、堆區、全局區/靜態區和代碼區。
這里去掉自由存儲區,增加了代碼區,理由會在下面講到。
棧區:由系統進行內存的管理。
說明:主要存放函數的參數以及局部變量。棧區由系統進行內存管理,在函數完成執行,系統自行釋放棧區內存,不需要用戶管理。整個程序的棧區的大小可以在編譯器中由用戶自行設定,默認的棧區大小為3M。
堆區:由用戶手動申請,手動釋放。在C中使用malloc,在C++中使用new(當然C++中也可以使用malloc)。
全局/靜態區:全局、靜態數據存放在一起的,初始化的全局變量和靜態變量是在一起的。未初始化的全局變量和靜態變量是在相鄰的空間中。這里包括常量區。
代碼區:存放程序體的二進制代碼。比如我們寫的函數,都是在代碼區的。
二、C語言的代碼內存布局詳解
一個程序本質上都是由 BSS 段、data段、text段三個組成的。這樣的概念在當前的計算機程序設計中是很重要的一個基本概念,而且在嵌入式系統的設計中也非常重要,牽涉到嵌入式系統運行時的內存大小分配,存儲單元占用空間大小的問題。
BSS段:在采用段式內存管理的架構中,BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內
存區域。BSS是英文Block Started by Symbol的簡稱。BSS段屬于靜態內存分配。
數據段:在采用段式內存管理的架構中,數據段(data segment)通常是指用來存放程序中已初始化的全局變量的一塊內
存區域。數據段屬于靜態內存分配。
代碼段:在采用段式內存管理的架構中,代碼段(text segment)通常是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經確定,并且內存區域屬于只讀。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
程序編譯后生成的目標文件至少含有這三個段,這三個段的大致結構圖如下所示:

其中.text即為代碼段,為只讀。.bss段包含程序中未初始化的全局變量和static變量。data段包含三個部分:heap(堆)、stack(棧)和靜態數據區。
堆(heap):堆是用于存放進程運行中被動態分配的內存段,它的大小并不固定,可動態擴張或縮減。當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)
棧 (stack):棧又稱堆棧, 是用戶存放程序臨時創建的局部變量,也就是說我們函數括弧“{}”中定義的變量(但不包括static聲明的變量,static意味著在數據段中存放變 量)。除此以外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,并且待到調用結束后,函數的返回值也會被存放回棧中。由于棧的先進先出特點,所以 棧特別方便用來保存/恢復調用現場。從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時數據的內存區。
正確的C++/C內存布局及兩者的區別
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
- 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...