首先,了解一下c / c++的記憶體分布,c/c++中程式記憶體區域一共劃分為六段:
核心空間:程式記憶體一般為4g,1g為核心空間這個區域使用者不能讀寫,3g為使用者空間時使用者可以操作的;
棧:一般儲存非靜態區域性變數,函式引數,返回值等,由上向下增長;
記憶體對映段:裝在乙個共享的動態記憶體庫,使用者可以使用系統介面建立共享記憶體,做程序間通訊;
堆:用於儲存動態記憶體分配的變數,如:malloc, new建立的變數都是儲存在堆上,堆時自下而上儲存;
資料段:儲存全域性資料,靜態成員。如:static成員
**段:可執行**儲存的地方,還有唯讀常量也儲存在**段,如:字串常量。
c中的記憶體管理方式:
在c語言中,有一些庫函式可以實現記憶體管理:
int
* p1 =
(int
*) malloc (
sizeof
(int)*
4);//開闢4個int大小的空間,只開闢,不初始化
int* p2 =
(int*)
realloc
(p1,
sizeof
(int)*
10);//將空間調整成10個int大小的空間,如果比原空間小,就在原空間基礎上
//減小空間,如果比原空間大,判斷後續空間是否足夠,不足夠就重新開闢空間,把原空間記憶體拷貝過去
//如果足夠,就在原空間的基礎上擴容空間
int* p3 =
(int*)
calloc(4
,sizeof
(int))
;//開闢4個int空間,並按位初始化為0,即開闢空間同時初始化
free
(p1)
;free
(p2)
;free
(p3)
;//開闢的所有空間在用完之後必須釋放,不然會導致記憶體洩漏
c++記憶體管理方式:
new / delete操作符在c++中進行開闢記憶體和釋放記憶體的工作。
對於內建型別而言,new 和 delete 與malloc 和 free類似。
int
* a =
newint
;//申請乙個int型別空間
int* b =
newint(10
);//申請乙個int型別空間,並初始化為10
int* c =
newint[10
];//申請10個連續int型別空間
delete a, b;
delete
c;//釋放連續空間
如果建立多維陣列,就得一維一維建立,並且由最後建立的向第乙個建立的依次釋放,以二位陣列為例:
int
**array
// 假定陣列第一維長度為 m, 第二維長度為 n
// 動態分配空間
array =
newint
*[m]
;for
(int i=
0; i)//釋放
for(
int i=
0; i)delete
array;
對於自定義型別而言,new會呼叫這個類的建構函式來建立物件,delete會呼叫這個類的析構函式來釋放物件。
需要注的是在使用new[ ]建立連續多個物件的時候,類中必須有預設建構函式。
operator new 和 operator delete
operator new 和 operator delete是系統提供的全域性函式,
new 和 delete的底層其實就是呼叫operator new 和 operator delete函式。
operator new 相當於乙個封裝好的malloc + 異常,實際上還是使用malloc開闢空間。
operator delete 相當於封裝了free。
由此,可以看出若是使用 new 和 delete操作符,將其步驟層層深入相當於:
new -> operator new -> malloc + 異常 -> 建構函式(自定義型別)
delete -> 析構函式(自定義型別) -> operator delete -> free
不同的是,如果是自定義型別,new會先開闢空間然後呼叫建構函式初始化,delete會先呼叫析構函式清理資源,然後呼叫free釋放空間。
new定位表示式
顯示呼叫建構函式初始化空間,先申請空間再顯示呼叫建構函式,常用與記憶體池配合使用。
new(位址) 型別 //前面需要已經開闢空間
這邊就得提一下記憶體池,首先,記憶體池是什麼?
記憶體池是乙個物件池,我們使用記憶體物件之前,先申請分配一定數量的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊不夠再繼續申請新的記憶體,當不需要此記憶體時,重新將此記憶體放入預分配的記憶體塊中,下次繼續使用,這樣合理的分配**記憶體使記憶體分配效率得到提公升。
為什麼會有記憶體池??
由於我們每次使用new申請的記憶體大小不定,頻繁的申請就會產生大量的記憶體碎片,而且頻繁的分配和釋放記憶體會降低效能,因為物件的析構和構造都需要時間,
關於記憶體洩漏
記憶體洩漏就是一塊記憶體不再使用了,卻沒有及時釋放。系統失去了對這段記憶體的控制,造成記憶體的浪費。
記憶體洩漏分為兩種:
堆記憶體洩漏
常見的就是使用 malloc new 等從堆中分配記憶體的時候,用完之後沒有及時的free 或 delete。導致這部分空間無法再使用。
系統記憶體洩漏
程式使用系統分配的資源,比如:套接字,檔案描述符,管道等沒有使用對應的函式釋放掉,導致系統資源的浪費,嚴重可導致系統效能減少,系統執行不穩定。
如何避免和解決記憶體洩漏?
有良好的程式設計習慣,嚴謹的思維;採用raii思想或者智慧型指標,使用記憶體洩漏檢測工具。
C 記憶體管理 C 記憶體分類
c 記憶體管理 記憶體分類 moakap 在編寫程式過程中,程式設計師必須清楚程式記憶體的分配機制,合理進行記憶體管理,這樣才能得到高效的程式。同時,如果對c 記憶體分配基本概念不理解,使用不當,一方面浪費了寶貴的記憶體資源,降低了程式執行效率,另一方面還會造成程式中意想不到的錯誤。在 c 程式中,...
C 記憶體管理
在嵌入式系統中使用c 的乙個常見問題是記憶體分配,即對new 和 delete 操作符的失控。具有諷刺意味的是,問題的根源卻是c 對記憶體的管理非常的容易而且安全。具體地說,當乙個物件被消除時,它的析構函式能夠安全的釋放所分配的記憶體。這當然是個好事情,但是這種使用的簡單性使得程式設計師們過度使用n...
c 記憶體管理
這裡對我暫時所了解的記憶體機制做個記錄,以後再補。首先是記憶體分配 記憶體主要分為3個部分 一是從靜態儲存區域分配。編譯時分配好,主要存放全域性變數,static變數,程式結束釋放。二是從堆疊區域分配。函式內區域性變數存放的地方。隨變數生命週期自動釋放。效率較高,但大小有限。三是從記憶體池分配,即從...