C++内存分类
1 棧
存放的數據:
局部變量,函數參數,返回地址等。
默認初始值:
無默認初始值,為隨機值。
分配者:
有編譯器自動分配。
分配大小:
在程序開始后分配固定大小的棧空間,如果申請空間大于剩余棧空間,那么分配失敗。
生長方向:
棧空間的生長方向是從高地址向低地址生長,即后申請的變量的地址小于先申請的變量的地址。
溢出:
如果新申請的變量小于剩余棧空間(因為分配是固定的棧大小),就會溢出。
特點:
系統自動分配,申請效率高,但程序員無法控制。
是否連續:
連續。
分配過程:
變量作用域:
局部作用域,它是自動對象(auto),在程序運行期間不是一直存在,而是只在函數執行期間存在,函數的一次調用執行結束后,變量被撤銷,其所占用的內存也被收回。
2 堆
存放的數據:
由程序員動態(在代碼中)申請的空間。
分配者:
由程序員申請,操作系統分配。
大小是否固定:
大小不是固定的,是由程序員決定每次申請空間的大小。
分配過程:
申請堆空間,堆在內存中呈現的方式類似于鏈表(記錄空閑地址空間的鏈表),在鏈表上尋找第一個大于申請空間的節點分配給程序,將該節點從鏈表中刪除。大多數系統中該塊空間的首地址存放的是本次分配空間的大小。
在C中,可以使用malloc和calloc進行申請,兩個函數都返回申請內存的首地址。兩者的區別為:
- 兩者參數個數不同:malloc只有一個參數,即你要分配的字節數,calloc有兩個參數,一個為單元個數,另一個為每個單元大小
- 兩者初始化不同:malloc不對分配的空間進行初始化,所以內存中是隨機值。而calloc會將分配的空間初始化為0
溢出:
生長方向:
堆的生長方向為低地址向高地址生長。
回收:
程序員手動釋放,如果程序結束時申請的空間還未釋放,那么操作系統會自動將其回收。釋放后,該塊空間會被再次鏈接到鏈表上。在申請時,如果該節點還有剩余空間,也會將剩余空間連接到鏈表上。
默認初始值:
特點:
堆是由程序員主動申請,效率低,使用起來方便但是容易產生碎片。
是否連續:
不連續。
3 全局/靜態存儲區
存放的數據:
全局變量,靜態全局變量,靜態局部變量
由誰分配:
大小是否固定:
溢出:
生長方向:
回收:
程序結束之后操作系統自動將其釋放。
默認初始值:
(記得時0,但是不確定)
特點:
在C中分為.bss段和.data段,未初始化的放在.bss段中, 初始化的放在.data中,在C++中不再區分。
是否連續:
分配過程:
變量作用域:
- 全局變量的作用域是全局作用域,全局變量只需在一個源文件中定義,就可以作用于所有的源文件。當然,其他不包含全局變量定義的源文件需要用?extern?關鍵字再次聲明這個全局變量。
-
靜態全局變量具有文件作用域。它與全局變量的區別在于如果程序包含多個文件的話,它作用于定義它的文件里,不能作用到其它文件里,即被 static 關鍵字修飾過的變量具有文件作用域。這樣即使兩個不同的源文件都定義了相同名字的靜態全局變量,它們也是不同的變量。
-
靜態局部變量具有局部作用域。它只被初始化一次,自從第一次被初始化直到程序運行結束都一直存在,它和全局變量的區別在于全局變量對所有的函數都是可見的,而靜態局部變量只對定義自己的函數體始終可見。
注意,全局變量最好不要在頭文件中定義,除非能保證該頭文件只被包含一次。因為include頭文件是將頭文件代碼插入到引用位置,所以全局變量定義到頭文件會使得該變量被重復定義。
4 常量存儲區
存放的數據:
存放的是常量,不允許修改
由誰分配:
大小是否固定:
溢出:
生長方向:
回收:
程序結束之后操作系統自動將其釋放。
默認初始值:
特點:
是否連續:
分配過程:
變量作用域:
5 代碼區
存放的數據:
存放代碼,不允許修改,但可以執行。編譯后的二進制文件存放在這里。
由誰分配:
大小是否固定:
溢出:
生長方向:
回收:
默認初始值:
特點:
是否連續:
分配過程:
變量作用域:
總結
- 上一篇: 操作系统进程管理
- 下一篇: matlab热度图确定色标_C++实现类