c語言:動態內存知識點(申請、釋放、free崩潰的原因)

動態內存

用戶無法確定空間大小,或者空間太大,棧上無法分配時,會採用動態內存分配,存放於堆(heap)區,不能通過變量名或數組名引用,只能通過指針引用.

1、在Windows操作系統中,堆中最大連續內存大概1.3G。

2、最大問題:內存泄漏(軟件開發設計考慮的主要方面,每次泄露少量,久而久之很多,導致程序運行速度減慢甚至導致系統崩潰。)

3、內存不足時返回空指針。

4、返回類型是void*類型,表示未確定類型的指針,void*可以強轉爲任何其他類型指針。

5、主要函數  malloc(),  calloc(),  realloc(),  free().頭文件:#include<stdlib.h>

malloc

用於申請一塊連續的指定大小的內存塊區域

 函數原型:void *malloc (unsign int size)

參數:size

int *p = (int*)malloc(n*sizeof(int));   //int [p]

返回值:如果分配成功則返回指向被分配內存的指針(此存儲區中的初始值不確定),否則返回空指針NULL。當內存不再使用時,應使用free()函數將內存塊釋放。函數返回的指針一定要適當對齊,使其可以用於任何數據對象

sizeof(int)儘量不使用具體數據類型數值

原因:自定義數據類型不容易得到數值

          不同平臺數值可能不同。(跨平臺問題)

calloc

 calloc用於將所有元素賦值初始值爲0

 函數原型:void *calloc(unsigned num,unsigned size)

參數:num(元素的數目),size(申請地址的單位元素長度)

int *p = (int*)calloc(100,sizeof(int));

 malloc和calloc之間的主要區別:calloc在返回指向內存的指針之前把它初始化爲0。

沒有malloc常用

realloc

調整動態內存,主要用於擴大內存

函數原型: void*realloc(void *p,unsigned int size)

參數:p(要改變內存大小的指針名),size(新的內存大小)

p = (int*)realloc(p,20*sizeof(int));

使用總結
1. realloc失敗的時候,返回NULL
2. realloc失敗的時候,原來的內存不改變,不會釋放也不會移動

3. 如果是擴大內存,先進行判斷,如果當前指針有足夠的連續空間,不用重新申請內存,直接在後面附加;如果空間不夠,按照新的內存大小重新在堆中申請內存,將原有數據拷貝到新內存區域,並且釋放原有指針空間(注意:是自動釋放,不需要使用free),同時返回新分配的內存區域首地址。

 如果它用於縮小一個內存塊,原空間不變,服務器不會對此作出改變。

4. 如果size爲0,效果等同於free()。這裏需要注意的是隻對指針本身進行釋放,例如對二維指針**a,對a調用realloc時只會釋放一維,使用時謹防內存泄露。
5. 傳遞給realloc的指針必須是先前通過malloc(), calloc(), 或realloc()分配的
6.傳遞給realloc的指針可以爲空,等同於malloc。

free

 執行動態內存釋放,防止內存泄漏內存

對於不再使用的動態分配的內存空間,可以通過內存釋放free函數將其返還給堆供後續分配函數使用

 函數原型:void free(void *p)

參數:p

free(p);

通過以上的存儲方式結構圖可以看出有頭信息和尾信息,每一段中間有空白區域,所以free 不需要長度信息。

free崩潰的原因:

  1、越界,漏寫sizeof(),或者realloc()第二個參數錯誤。

int main()
{
	int *p1 = (int *)malloc(20);
	for(int i=0;i<20;i++)
	{
		p1[i] = 0;
	}
 
	free(p1);
	return 0;
}

  2、指針移動,找不到頭(修改了指針的值)

int main()
{
	int *p = (int *)malloc(10*sizeof(int));
	for(int i=0;i<10;i++)
	{
		*p = 0;
		p++;      //不free不崩潰
	}
	free(p);     //崩潰
	return 0;
}

  3、重複釋放內存

int main()
{
	int *p = (int *)malloc(10*sizeof(int));
	int *q = p;
	free(p);
	free(q);
 
	return 0;
}

  4、釋放不是動態創建的內存(非動態內存)

int main()
{
	int a = 10;
	free(&a);
 
	return 0;
}

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