動態內存管理

動態內存分配
一、C語言內存分配
一、malloc
1、按字節分配內存空間,分配的內存空間不初始化
2、返回類型爲void*
3、函數只有一個參數
原型:void* malloc(size_t size);//size是字節個數

二、calloc
1、按字節分配內存空間,分配的內存空間進行初始化爲0
2、返回類型爲void*
3、函數有二個參數,按類型字節大小和個數開闢內存空間
原型:void* malloc(size_t count,size_t size);//count是個數,size是類型大小

三、realloc
1、動態調整內存大小
2、按字節調整內存大小
2、返回原類型void*  void* realloc(void* ptr,size_t newsize);//ptr所要開闢內存的指針,newsize開闢的字節數
3、函數有二個參數,調整內存空間的指針和所要調整的大小
4、當原指針爲空時,同於malloc開闢內存空間
5、當原指針不爲空時,
(1)指針處有足夠的的內存空間,則直接進行擴容,增大內存空間,原指針地址不變
(2)指針處無足夠的內存空間,則重新尋找一塊足夠的內存空間,並把數據拷到新空間中,釋放就舊空間,返回新空間地址。原指針地址發生改變
(3)無足夠內存空間返回NULL,數據據丟失。所以建議不要使用原指針接收返回的地址,而用臨時指針接收返回的地址,空間開闢成空(非NULL),再指向臨時指針
防止數據丟失。
問題:realloc若所要開闢的內存空間小於原內存空間,則結果爲多少?開闢0個空間則會是怎樣的?
答:若指定的空間小於原空間,則空間會縮小,截除後部分的數據,返回原指針。開闢空間大小爲0時,釋放原空間返回NULL
注:不管使用那種方式管理內存空間,都需對返回值進行判斷,判斷空間是否開闢成功,成功返回非NULL,失敗返回NULL;
釋放內存空間---->free()
開闢的內存空間只能整塊釋放,不可部分釋放。即釋放的指針與開闢空間返回的指針必須相同。

C++動態內存管理
開闢內存---->new
1、new自動計算類型大小,按個數開闢內存空間,返回類型爲對應的指針類型
2、new和delete爲操作符不爲函數
3、new和delete的底層是使用malloc和free實現的。

使用方法:
開闢一個int類型的空間
p1 = new int; --------------->delete p1
開闢一個int類型的空間,初始化爲1
p2 = new int(1); ------------>delete p2
開闢3個int類型對象的空間,注次數是調用3次構造函數,最終也會調用3次析構函數
p3 = new int[3]; ------------>delete []p3
new 類型[] 開闢內存空間時會多開闢4個字節的空間,用於在頭部保存開闢內存空間的個數,返回時向後偏移4個字節的空間,析構時會再向前偏移4個字節釋放空間。
所以delete釋放空間時,必須與new開闢的方法對應,否則會因空間釋放位置不正確導致出錯。
new和free也不可混用,否則可能會出現內存泄露的危險
因爲:對於自定義類型的對象,在定義時會調用構造函數進行初始化。銷燬時會調用析構函數進行銷燬。
析構時會先清理類內部成員的空間,後釋放對象空間,防止內存泄露。若使用free釋放空間,則可能由於類內部成員空間未釋放,導致內存泄露

注:雖然使用new---->free操作內置類型不會出錯,但也不要這樣使用。這樣容易導致誤解和可讀性低。
不出錯是由於編譯器對內置類型進行了優化,未調用構造函數,和析構函數。

其它類型接口:
void* operator new(size_t size);
void* operator new[](size_t size);
void* operator delete(void* ptr);
void* operator delete[](void* ptr);
注:以上函數不是重載關係,是特列
new = operator new + 構造函數 = malloc+拋異常
delete = operator delete + 析構 = free+拋異常
//假設開闢10個空間
new xx[10] = operator new[] + 10次構造 = malloc(sizeof(xx)*10)+拋異常
delete []_a = operator delete[] + 10次析構 = free+拋異常
空間開闢與釋放方法不匹配,是否會導致出錯,主要看是否會多或少釋放4個字節的空間問題。會就會導致程序崩潰。
計算機判斷空間或數組越界訪問的方法是,多開闢幾個字節的空間並初始化爲某個值,如0xcccccccc,當檢測到這些值被修改時,則認爲越界。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章