前言
C\C++提供了底層的內(nèi)存操作枕赵,為程序提供了強(qiáng)大的能力猜欺。在使用 malloc() calloc() realloc()
進(jìn)行動(dòng)態(tài)內(nèi)存分配時(shí),內(nèi)存區(qū)域中的這個(gè)空間稱為堆(heap)拷窜,另一個(gè)內(nèi)存區(qū)域开皿,稱為棧(stack),其中的空間分配給函數(shù)的參數(shù)和本地變量篮昧,執(zhí)行完該函數(shù)后赋荆,存儲(chǔ)參數(shù)和本地變量的內(nèi)存空間就會(huì)自動(dòng)釋放宾舅。而堆中的內(nèi)存是由人控制的咳秉,在分配堆上的內(nèi)存時(shí),需要人自己來(lái)判斷什么時(shí)候需要分配昧辽,什么時(shí)候需要釋放酵颁。
malloc
- 函數(shù)原型
(TYPE *) malloc(SIZE)
- 函數(shù)功能
malloc()
在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配一塊長(zhǎng)度為SIZE
字節(jié)的連續(xù)區(qū)域嫉你。參數(shù)SIZE
為需要的內(nèi)存空間的長(zhǎng)度月帝,返回該區(qū)域的地址。malloc()
函數(shù)不能為所分配的空間初始化值幽污,需要使用memset()
嚷辅,不然可能會(huì)出現(xiàn)內(nèi)存中遺留的數(shù)據(jù)。在程序結(jié)束前距误,需要使用free()
進(jìn)行內(nèi)存釋放簸搞。 - 使用
int *p = NULL;
p = (int *) malloc(sizeof(int)); // 申請(qǐng)
memset(p, 20, sizeof(int) / 4); // 賦初值(不可取)
printf("%d\n", *p); // 20
free(p); // 釋放
主要注意的是准潭,memset()
是按照字節(jié)來(lái)進(jìn)行賦值趁俊,而 char
類型的空間恰好是1字節(jié),所以 memset()
最好用于 char
類型的賦值惋鹅。當(dāng)然则酝,也可以用 sizeof(int) / 4
來(lái)給 int
類型賦值,只不過(guò)只能賦 0x00 - oxff 的值闰集。不然的話就是按位賦值四次沽讹。
char *p = NULL;
p = (char *) malloc(sizeof(char));
memset(p, 'g', sizeof(char));
printf("%c\n", *p); // g
free(p);
p = NULL;
如上,char
類型可以完美的賦值武鲁。
calloc
- 函數(shù)原型
(TYPE * )calloc(int n, SIZE);
- 函數(shù)功能
calloc()
函數(shù)功能和malloc
類似爽雄,都是從堆內(nèi)存中分配內(nèi)存,不同的是沐鼠,calloc()
會(huì)自動(dòng)進(jìn)行初始化挚瘟,每一位都初始化為零。n
表示元素的個(gè)數(shù)饲梭,SIZE
為單位元素的長(zhǎng)度乘盖,從定義上看,calloc()
適合為數(shù)組申請(qǐng)動(dòng)態(tài)內(nèi)存憔涉。與malloc()
最后也需要使用free()
進(jìn)行內(nèi)存釋放订框。 - 使用
#define SIZE 10
int *p;
p = (int *) calloc(SIZE, sizeof(int));
for (int i = 0; i < SIZE; ++i) {
p[i] = i;
}
for (int j = 0; j < SIZE; ++j) {
printf("%d\n", p[j]); // 0, 1, 2, 3, 4, 5 ...
}
free(p);
p = NULL;
realloc
- 函數(shù)原型
(TYPE * )realloc(TYPE *ptr, NEW_SIZE);
- 函數(shù)功能
realloc()
是給一個(gè)已經(jīng)分配了地址的指針重新分配動(dòng)態(tài)內(nèi)存空間,*ptr
為原有的空間地址兜叨,NEW_SIZE
是重新申請(qǐng)的空間穿扳,若新的空間小于之前的空間,則不會(huì)進(jìn)行改變国旷,若新的空間大于原來(lái)的空間矛物,則會(huì)從堆內(nèi)存中為*ptr
分配一個(gè)大小為NEW_SIZE
的空間嗎,同時(shí)將原來(lái)空間的內(nèi)容依次復(fù)制進(jìn)新的地址空間跪但,*ptr
之前的空間被釋放履羞,realloc()
所分配的空間也是未初始化的。 - 使用
#define SIZE 10
int *p;
p = (int *) calloc(SIZE, sizeof(int));
for (int i = 0; i < SIZE; ++i) {
p[i] = i;
}
p = (int *) realloc(p, SIZE * 2);
for (int j = 10; j < SIZE * 2; ++j) {
p[j] = j;
}
for (int k = 0; k < SIZE * 2; ++k) {
printf("%d\n", p[k]); // 1, 2, 3, ... , 19
}
free(p);
p = NULL;