目錄
一、為什么存在動態記憶體分配
二、動態記憶體函式
malloc和free
calloc
realloc
一、為什么存在動態記憶體分配
之前我們學過的開辟空間的方式就是如下兩種:
int main()
{
int a = 5;
char ch = 'b';
int arr[20] = { 0 };
}
以上的開辟記憶體的方式都是開辟好記憶體之后所開辟的記憶體是固定的,不能改變的,這種開辟方式不夠靈活
C語言里面的動態開辟記憶體就解決了這個問題
在學習C語言的時候通常大致將記憶體劃分為三部分:堆疊區,堆區,靜態區

動態開辟記憶體就是在堆疊上面開辟的空間
二、動態記憶體函式
malloc和free
malloc函式原型
void *malloc( size_t size );
引數:size_t size,就是想要開辟多大一塊空間(以位元組為單位),型別為無符號整型
回傳值:void*型別的指標,就是回傳所開開辟的這塊空間的起始地址,將來這塊空間用來存什么型別的資料是不確定的,所以是void*型別;如果記憶體開辟失敗,就回傳空指標(NULL)
頭檔案:<stdlib.h>
如果引數size 為0,malloc的行為是標準是未定義的,取決于編譯器
如下示例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ps = (int*)malloc(100);
if (ps == NULL)
{
perror("malloc:");
}
else
{
for (int i = 0; i < 50; i++)
{
*(ps + i) = i;
}
for (int i = 0; i < 50; i++)
{
printf("%d ", *(ps + i));
}
}
return 0;
}
分析:
因為我們想要用動態開辟的空間來存整型資料,所以就用整型指標來接受回傳值,并且需要強制型別轉換,然后用if陳述句來檢驗是否開辟成功,若失敗,用perror來列印錯誤資訊,若成功,則在后面使用這塊空間,對前50個空間賦值為0-50,并列印出來
運行結果:
![]()
但是這還并沒有完,因為我們向記憶體開辟空間用完之后就得還給作業系統,不然的話,這塊空間自己不用了,但別人也用不了,還在浪費記憶體,造成了記憶體泄漏的問題,這里用free來釋放記憶體
free原型
void free (void* ptr);
這樣來用
free(ps); //釋放記憶體
ps = NULL; //將指標置空
因為free(ps)釋放記憶體之后ps這個指標里面仍然還有這塊空間的地址,所以我們應該要將ps及時置空,不然后面如果用ps來訪問的話,就是非法的
- 如果引數ptr 指向的空間不是動態開辟的,那free函式的行為是未定義的
- 如果引數ptr 是NULL指標,則函式什么事都不做
calloc
函式原型:
void *calloc( size_t num, size_t size );
引數:
size_t num 這是指定要存放多少個元素
size_t size 指定所要存放元素的每個元素的大小
這個函式會將所開辟的空間自動初始化為0
回傳值:void*型別,若開辟成功,回傳所開辟空間的地址,開辟失敗,回傳空指標
頭檔案:<stdlib.h>
使用:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ps = (int*)calloc(10,sizeof(int));
if (ps == NULL)
{
perror("malloc:");
return 0;
}
for (int i = 0; i < 10; i++)
{
printf("%d ", *(ps + i));
}
free(ps);
ps = NULL;
return 0;
}
realloc
這個函式用來動態調整所開辟的記憶體大小,realloc函式的出現讓動態記憶體管理更加靈活
函式原型:
void *realloc( void *memblock, size_t size );
引數:memblock,要調整的記憶體的地址
size,調整之后的大小
回傳值:調整之后記憶體的起始地址void*型別
頭檔案:<stdlib.h>
使用:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ps = (int*)calloc(10,sizeof(int));
if (ps == NULL)
{
perror("malloc:");
return 0;
}
//調整大小
int* ptr = (int*)realloc(ps, 20 * sizeof(int));
if (ptr == NULL)
{
perror("realloc");
}
else
{
ps = ptr;
ptr = NULL;
}
for (int i = 10; i < 20; i++)
{
*(ps + i) = i;
}
for (int i = 0; i < 20; i++)
{
printf("%d ", *(ps + i));
}
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/333793.html
標籤:其他
