原文:
正確的理解c/c++程式的記憶體分割槽,是合格程式猿的基本要求。
網路上流形兩大版本記憶體分割槽,分別為:
1. 五大記憶體分割槽:堆、棧、全域性/靜態儲存區、自由儲存區和常量儲存區。
2. 五大記憶體分割槽:堆、棧、全域性/靜態儲存區、字串常量區和**區。
且不論以上兩種分割槽孰是孰非,孰優孰劣,我認為具體的記憶體分割槽和編譯器有很大關係,我想不同編譯器對記憶體的劃分都不盡相同,但也大同小異。
綜合對比,查閱相關資料,提出自己對c/c++程式的記憶體分割槽的認識。可劃分為四大記憶體分割槽:堆、棧、靜態儲存區和**區。
堆區:
由程式猿手動申請,手動釋放,若不手動釋放,程式結束後由系統**,生命週期是整個程式執行期間。使用malloc或者new進行堆的申請,堆的總大小為機器的虛擬記憶體的大小。
說明:new操作符本質上是使用了malloc進行記憶體的申請,new和malloc的區別如下:
(1)malloc是c語言中的函式,而new是c++中的操作符。
(2)malloc申請之後返回的型別是void*,而new返回的指標帶有型別。
(3)malloc只負責記憶體的分配而不會呼叫類的建構函式,而new不僅會分配記憶體,而且會自動呼叫類的建構函式。
棧區:
由系統進行記憶體的管理。主要存放函式的引數以及區域性變數。在函式完成執行,系統自行釋放棧區記憶體,不需要使用者管理。整個程式的棧區的大小可以在編譯器中由使用者自行設定,vs中預設的棧區大小為1m,可通過vs手動更改棧的大小。64bits的linux預設棧大小為10mb,可通過ulimit -s臨時修改。
靜態儲存區:
靜態儲存區內的變數在程式編譯階段已經分配好記憶體空間並初始化。這塊內存在程式的整個執行期間都存在,它主要存放靜態變數、全域性變數和常量。
注意:
(1)這裡不區分初始化和未初始化的資料區,是因為靜態儲存區內的變數若不顯示初始化,則編譯器會自動以預設的方式進行初始化,即靜態儲存區內不存在未初始化的變數。
(2)靜態儲存區內的常量分為常變數和字串常量,一經初始化,不可修改。靜態儲存內的常變數是全域性變數,與區域性常變數不同,區別在於區域性常變數存放於棧,實際可間接通過指標或者引用進行修改,而全域性常變數存放於靜態常量區則不可以間接修改。
(3)字串常量儲存在靜態儲存區的常量區,字串常量的名稱即為它本身,屬於常變數。
(4)資料區的具體劃分,有利於我們對於變數型別的理解。不同型別的變數存放的區域不同。後面將以例項**說明這四種資料區中具體對應的變數。
**區:
存放程式體的二進位制**。比如我們寫的函式,都是在**區的。
示例**:
int a = 0;//靜態全域性變數區
char *p1; //編譯器預設初始化為null
void main()
以上所有**,編譯成二進位制後存放於**區,文字常量存放於**區,是不可定址的。
在理解c/c++記憶體分割槽時,常會碰到如下術語:資料區,堆,棧,靜態儲存區,靜態區,常量區,常變數區,全域性區,字串常量區,靜態常量區,靜態變數區,文字常量區,**區等等,初學者被搞得雲裡霧裡。在這裡,嘗試捋清楚以上分割槽的關係。
資料區包括:堆,棧,靜態儲存區。
靜態儲存區包括:常量區(靜態常量區),全域性區(全域性變數區)和靜態變數區(靜態區)。
常量區包括:字串常量區和常變數區。
**區:存放程式編譯後的二進位制**,不可定址區。
可以說,c/c++記憶體分割槽其實只有兩個,即**區和資料區。
C C 的四大記憶體分割槽
正確的理解c c 程式的記憶體分割槽,是合格程式猿的基本要求。網路上流形兩大版本記憶體分割槽,分別為 1.五大記憶體分割槽 堆 棧 全域性 靜態儲存區 自由儲存區和常量儲存區。2.五大記憶體分割槽 堆 棧 全域性 靜態儲存區 字串常量區和 區。且不論以上兩種分割槽孰是孰非,孰優孰劣,我認為具體的記憶...
2020 12 16 c語言四大記憶體分割槽
c語言四大記憶體分割槽 分別是棧區 stack 堆區 heap bss段 bss 資料段 data 段 text 1.棧 在函式中定義的變數存放的記憶體區域。常見的int float char等變數均存放於棧區中,它的特點是由系統自動分配與釋放,不需要程式設計師考慮資源 的問題,方便簡潔。ps 棧區...
C 的五大記憶體分割槽
一 五大記憶體分割槽 在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。堆,就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用...