動態內存管理分析

內存區域的劃分

內存可以大塊劃分爲系統佔用不可訪問的區域,剩下就是棧,堆,代碼段,數據段(靜態區)。
那麼他們是如何分佈在內存中的呢?
可以瞭解一下函數棧幀
內存分佈
棧和堆都可以存放數據
注意:棧是從高地址到低地址生長的,而堆與它相反。

靜態區是存放初始化和未初始化

代碼段就是存放代碼啦

C/C++中堆上的內存管理

在C/C++上內存管理分爲兩種:

1. 系統自動分配自動回收。

2. 手動分配手動釋放

那麼什麼是系統自動分配自動釋放的呢?
棧!在棧上分配的空間是系統自動分配自動回收,不用程序員自己管理,很是方便,但是有好就有壞,棧的空間比較小,在linux操作系統下默認是8M大小的棧,所以過度用棧很容易導致棧溢出。
手動管理的動態內存在堆上,那麼可能會有疑問,堆有多大?可以說堆是非常大,這個其中存在這虛擬內存,詳細自行百度。
(實際自己學術淺薄不能解釋清楚^_^)

C++中在堆上開闢空間的關鍵字new及具體的實現

c++是C語言的加強版,也可以說是在C語言的基礎上添加了需要多新的特性,比如,面向對象,當然也會添加一些關鍵字。new,delete就是其中的兩個。
new關鍵字是用來開闢動態內存,也就是在堆上內存的分配。在C語言中我們也學過在堆上開闢空間的幾個關鍵字,malloc ralloc calloc 都是在堆上開闢空間,而new關鍵字與他們不一樣的是,它們只管開闢空間其他都沒有,而new不一樣,new添加了異常機制。更加的適用與面向對象的開發。
看new的具體實現機制。
new的具體實現其實還是藉助了malloc的函數,在c++中new對malloc進行了封裝,怎麼封裝,在new關鍵字裏添加了operator new[] 這個函數,並且做了異常處理,在operator new[] 這個函數中還是用malloc實現的內存開闢。
new關鍵字的內部
這是在vs3013上對new的單步執行操作,就可以看到new裏面是一個operator new[]函數的實現。而operator new[] 函數裏面還可以進去可以看到用的是malloc來開闢空間,但是不能在vs2013上面進行測試,這個需要低一點版本才能看到,比如vs2008。

c++在堆上釋放空間delete和delete[]

首先說明爲什麼會有delete和delete[]兩個釋放空間的。這個前面沒有說到,其實是因爲new在開闢空間時候可以一次開闢多個相同類型的對象。用的方式比如:

int *p = new int[3];

這樣我就開闢出了3個int的空間。這樣我們就有了一個問題delete可以釋放一次new那麼對於同類型的多個對象重複釋放就尤爲繁瑣,而且在對象特別多的時候就很容易釋放錯誤,所有就有了與之對應的delete[]。

關於new[]多個對象而用一個delete[]來釋放的底層機制

new[] 在開闢空間的時候會多開出四個字節的空間,爲什麼要多開?因爲需要保存開闢多個對象的個數,這樣就可以很輕鬆的知道在初始化對象的時候需要調用幾次構造函數。當空間用完時候,手動釋放只需要一個delete[]系統就知道調用幾次析構函數。這些就基於new[]時候多開闢的那四個字節。
具體細節我們用圖示來看:
底層機制圖
這樣就很巧妙的解決了當開闢很多對象時候釋放多或者少的問題了。

注意

在自定義類型中用new[]纔會多開闢四個字節的空間,如果是內置類型就不會多開闢四個字節的大小

new、new[]與delete、delete[]的匹配問題

如果是這樣那麼是不是可以用new開闢出來的空間用delete[]來釋放?
答案是不行的。首先要明確new和new[]雖然大體上都是開闢開闢空間,但是他們是有很多不同的,比如上面的圖,是用new[]開闢出來的,就會自動的多開闢出四個字節,而new開闢空間就不會多開闢出四個字節的空間。(當然這裏說的是自定義類型)。
那麼用new開闢出來的空間能不能用delete[]釋放呢?是絕對不行的。
原因是用new開闢出來的空間沒有多開闢四個字節,而delete[]要多向前多釋放四個字節的空間,但那本來就不是自己的空間,所以會出現訪問內存出錯,而導致程序奔潰。
如果用new[]開闢出來的空間能不能用delete釋放呢?程序奔潰
因爲釋放位置錯誤。delete在釋放時候沒有向前移動四個字節。

那麼如果用new開闢的用free釋放可以嗎?我們想一想,用new開闢的用free釋放好像沒有什麼問題,但是仔細想想,new有異常機制,而且會調用構造函數,那麼在程序結束需要調用析構函數,delete會而free不會調用,那麼就有可能會造成內存泄漏。
如果用malloc開闢的空間那麼用delete釋放,想想會發生什麼
有可能會奔潰,因爲delete需要調用析構函數,如果析構函數中有內存的釋放,那麼就會奔潰。

如有不足,請多多指教~

發佈了74 篇原創文章 · 獲贊 35 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章