動态記憶體函數的介紹
在堆區開辟空間
malloc和free

申請一塊連續可用的空間,并傳回指向這塊空間的指針
如果開辟失敗,則傳回一個NULL指針,是以malloc的傳回值一定要做檢查
free(p);//當動态申請的空間不再使用的時候,就應該還給作業系統
p=NULL;//徹底斷開
malloc和free應該成對使用
calloc
(開辟後進行了初始化)
realloc
調整動态開辟記憶體的大小
1.如果p指向空間之後有足夠的記憶體空間可以追加,則直接追加,後傳回p
2.如果p指向的空間之後沒有足夠的記憶體空間可以追加,則realloc函數會重新找一個新的記憶體區域
開辟一塊滿足需要的空間,并且把原來記憶體中的資料拷貝回來,釋放舊的記憶體空間
最後傳回新開辟的記憶體空間位址
3.得用一個新的變量來接收realloc函數的傳回值
realloc第一個參數給空指針時功能和malloc一樣
int *p=realloc(NULL,40);//功能等價于malloc()
常見的動态記憶體錯誤
1、對NULL空指針進行解引用操作
int* p = (int*)malloc(40);
//不一定開辟成功,要對p進行相關的判斷
*p = 10;//malloc開辟空間失敗,對NULL指針解引用
2、對動态開辟記憶體的越界通路
int* p = (int*)malloc(40);//10個int
if (p == NULL)
{
return 0;
}
int i = 0;
//越界
for (i = 0; i <= 10; i++)//通路了11個元素
{
*(p + i) = i;
}
3、對非動态開辟記憶體使用free釋放
int a = 10;
int* p = &a;//a空間是在棧區上,不是動态開辟出來的
//...
//對非動态開辟記憶體使用free釋放
free(p);
p = NULL;
4、使用free釋放動态開辟記憶體的一部分
int* p = (int*)malloc(40);
if (p == NULL)
{
return 0;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*p++;
}
free(p);//p變化了,不是開頭了
5、對同一塊記憶體多次釋放
int* p = (int*)malloc(40);
if (p == NULL)
{
return 0;
}
//使用
//釋放
free(p);
//...
free(p);//重複釋放
free(p);後跟P=NULL;可避免
6、對動态開辟記憶體忘記釋放(記憶體洩漏)
動态開辟的空間一定要釋放,并且正确釋放,不能隻開辟不回收
while (1)
{
malloc(1);
}
柔性數組
結構中的最後一個元素允許是未知大小的數組,叫做【柔性數組】成員
特點:
結構中的柔性數組成員前面必須至少一個其他成員
sizeof傳回的這種結構大小不包括柔性數組的記憶體
包含柔性數組成員的結構用malloc()函數進行記憶體的動态配置設定,并且配置設定的記憶體應該大于結構的大小,以适應柔性數組的預期大小
優點:
1.友善記憶體釋放2.有利于通路速度