1. 引言
數組是存儲在連續內存位置的項的集合,在實際使用中,往往需要增加或減少數組長度,這種情況下出現了動態內存分配(Dynamic Memory Allocation)。在程序運行時,改變數據結構(例如數組)大小的過程就被定義爲C語言的動態內存分配。在 /usr/include/stdlib.h 頭文件中,C定義了4個函數,以方便C編程中的動態內存分配,它們是malloc()、calloc()、realloc()和free(),分別用於分配、重新分配和釋放內存。
2. 動態內存分配
2.1 malloc()和calloc()的使用方法
malloc(memory allocation的縮寫)方法用於動態分配具有指定大小的單個大塊內存。它返回void類型的指針,其指針類型可以靈活轉換,同時使用默認garbage value(內存中存儲的隨機值)初始化內存塊。其語法格式爲:
ptr = (指針轉換格式*) malloc(分配的字節數)
例如:
ptr = (int*) malloc(100 * sizeof(int));
一般情況下int佔用4字節,整個語句會分配400字節的內存,指針ptr以int形式存儲首字節的地址。如果空間不足,則分配失敗並返回空(NULL)指針。示例:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int i=0,num;
printf("Please input the number of memory, the suggest range is [0,256]: ");
scanf("%d",&num);
int * ptr;
ptr=(int *)malloc(num * sizeof(int));
if ( ptr == NULL )
{
printf("Your input number is out of range.\n");
exit(66);
}
else
{
while(i<num)
{
printf("ptr[%d] = %d, ptr address is %p\n", i, ptr[i], ptr+i);
i++;
}
}
free(ptr);
}
正常情況下打印分配的內存內容及地址:
Please input the number of memory, the suggest range is [0,256]: 2
ptr[0] = 0, ptr address is 0x16eb010
ptr[1] = 0, ptr address is 0x16eb014
如果需要分配的內存過大,返回空指針:
Please input the number of memory, the suggest range is [0,256]: 999999999
Your input number is out of range.
calloc(continuous allocation的縮寫)方法與malloc()類似,用於動態分配指定類型的指定數量的內存塊。它用默認值“0”初始化每個塊。語法格式爲:
ptr = (指針轉換格式*)calloc(元素總數, 單一元素所佔字節數);
2.2 malloc()和calloc()的區別
程序將它的可用內存分爲3部分來存儲變量:存儲靜態變量的靜態存儲區、存儲自動變量的棧、存儲動態分配變量的堆。靜態變量的生命週期貫穿程序始終;自動變量位於函數代碼塊中,隨着函數的逐層調用開始佔用內存,隨着函數調用結束反向釋放內存,符合棧後進先出的特點;動態分配變量的特點是可以在一個函數中創建內存塊,在其他函數中釋放,存取靈活的同時會造成內存使用的碎片化,所以動態內存往往導致進程比使用棧內存慢。
malloc()和calloc()是動態分配內存的庫函數,這意味着在程序執行時從堆(heap)中分配內存。它們的區別不大:
- 初始化:malloc()不初始化分配的內存,如果在初始化內存之前訪問內存內容,可能會得到 segmentation fault error 或是 garbage value;calloc()分配內存並將內存塊初始化爲0。
- 當malloc()分配單一元素的內存大小時,配合memset()函數實現與calloc()相同的功能。
ptr = malloc(size);
memset(ptr, 0, size);
一般使用malloc()而不是calloc(),因爲malloc()比calloc()快,除非需要將內存初始化爲0。如果需要複製內存,malloc將是一個更好的選擇。
2.3 free()和realloc()
free()方法用於動態地取消分配內存。使用函數malloc(和calloc()分配的內存不會自行釋放分配。因此,每當動態內存分配發生時,都會通過free()方法釋放內存來減少內存的浪費。語法爲:
free(ptr);
realloc(reallocation)方法用於動態更改以前分配的內存大小。換言之,如果先前藉助malloc或calloc分配的內存不足,則可以使用realloc動態擴大變量佔用的內存。原有內存塊將保持現有值,新塊將使用默認garbage value初始化。語法爲:
ptr = realloc(ptr, newSize);
where ptr is reallocated with new size 'newSize'.
參考文獻
[1] RishabhPrabhu.Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()[EB/OL].https://www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/,2020-01-01.
[2] chakradharkandula, shubham_singh, Navfal, HarshitHiremath.Difference Between malloc() and calloc() with Examples[EB/OL].https://www.geeksforgeeks.org/difference-between-malloc-and-calloc-with-examples/,2020-01-01.
[3] ElementLS.堆棧的知識[EB/OL].https://zhuanlan.zhihu.com/p/34681978,2018-03-21.