C++中的內存區域及其性能特征
首先須要指出的是。我們通經常使用“堆”和“自由存儲”這兩個術語來區分兩種不同類型的動態分配內存。
1.常量數據:常量數據區域主要用於存儲字符串以及其它在編譯期就已經知道值的數據。實例化的對象是不能存儲在?這?個區域中的。
在程序的整個生存期內。這個區域中的全部數據都是有效的。而且,全部這些數據都是僅僅讀的,假設對這些數據進行改動。其結果在C++中是未定義的。
造成這樣的後果的部分原因是編譯器可能會對常量數據的基本存儲格式進行隨意優化。
比如,在某個特定的編譯器中,可能會將字符串常量保存在重疊對象
???
2.棧:在棧中存儲的是自己主動變量。
自己主動變量在定義的時候被馬上構造,而且在自己主動變量作用域結束的時候被馬上銷毀,因此程序猿無法對已經分配但尚未初始化的棧空間直接進行操作(除非你有意識地使用顯示析構函數和布局new語法)。
棧內存的分配通常要比動態內存的分配(堆和自由存儲)快非常多,由於每次棧內存的分配僅僅涉及棧指針的自增操作,而無需進行更為復雜的內存管理。
3.自由存儲:自由存儲時兩種動態內存區域之中的一個。它是通過new/delete來分別進行分配/釋放。
對象的生存期可能會小於所分配的存儲空間的生存期。
也就是說,自由存儲區域中的對象在分配內存時並不要求馬上進行初始化。而且在銷毀對象時。也不要求馬上釋放內存空間。
在存儲空間已經被分配但還沒有進入到對象生存期的這段時間內,我們能夠通過一個void*類型的指針來訪問和操作這塊存儲空間。但我們不能訪問對象中不論什麽一個非靜態的成員或非靜態的成員函數。不能去獲得他們的地址,或者進行其它的操作。
4.堆:堆是還有一種動態內存區域,它是通過malloc()/free()函數以及這些函數的其它形式來進行分配/釋放的。
我們要註意的是,雖然在某個特定的編譯器中,默認的全局運算符new和delete可能會用函數malloc()和free()來進行實現,可是堆還是不同於自由存儲。在堆中分配的內存不能再自由存儲區域中被安全地釋放,反之亦然?在堆中分配的內存。能夠用於對象的placement new構造過程 和顯示的析構過程中。假設是這樣的使用方法。那麽自
5.全局/靜態:在程序啟動的時候,這些變量/對象或靜態的變量/對象就已經被分配了存儲空間,但僅僅有等到程序運行的時候,這些變量/對象才幹夠進行初始化。
比如:函數中的靜態變量僅僅有當程序第一次運行到變量的定義語句時才幹被初始化。
對於跨越多個編譯單元的全局變量,它們的初始化順序是未定義的。而且我們在管理全局對象(包含類的靜態成員)之間的依賴性的時候要特別小心。通常來說,我們能夠通過一個void*指針來對未初始化的對象存儲空間進行訪問和操作,但我們不能再對象的生存期之外來使用或者引用非靜態的成員變量或成員函數。
指導原則:我們應該優先使用自有存儲(new/delete),而且要避免去使用堆(malloc/free)。
??C++中的內存區域及其性能特征