自動分配內(nèi)存:當定義以基本類型的變量的時候,系統(tǒng)會地方為這個變量自動分配內(nèi)存,這個 內(nèi)存在堆上。當作用域結(jié)束,系統(tǒng)會自動將這個內(nèi)存回收。
動態(tài)分配內(nèi)存:開發(fā)人員自己向系統(tǒng)申請的內(nèi)存空間,申請的內(nèi)存位于棧上,當作用于結(jié) 束之后,系統(tǒng)是不會自動收回內(nèi)存的。這個內(nèi)存必須由開發(fā)人員自己去釋 放。如果不釋放,就內(nèi)存泄露了。用“free(void *)這個函數(shù)進行釋放,這里值得注意的是free的參數(shù)必須為指針,并且是動態(tài)內(nèi)存分配的。
△什么時候需要動態(tài)分配內(nèi)存?
程序運行過程中,需要保存/記錄相應(yīng)的數(shù)據(jù),但是又沒有提前準備好內(nèi)存,那么就需要臨時動態(tài)分配內(nèi)存。
△使用函數(shù):
void *malloc(size_t);
size_t: 希望申請的內(nèi)存空間(字節(jié)byte)
void * :系統(tǒng)一開始不知道你需要存放什么數(shù)據(jù),不同的數(shù)據(jù)需要的內(nèi)存空間不一樣,所以默認就是給一個void *,泛指所有指針類型(char *, int *, struct *),當在使用的時候必須將void *轉(zhuǎn)化為相應(yīng)的類型。如果沒有申請成功,那么返回值為NULL。
所以每次申請內(nèi)從空間之后都要檢驗是否成功開辟內(nèi)存空間。
△計算結(jié)構(gòu)體內(nèi)存空間
原理:如果結(jié)構(gòu)體內(nèi)部擁有多種數(shù)據(jù)類型,那么以占據(jù)內(nèi)存字節(jié)數(shù)最高的類型對齊
typedef struct{
char *name;
int age;
}Person;//16
char * 占據(jù)8個字節(jié), int 占據(jù)4個字節(jié)
所以age變量自動向name對齊。整個占據(jù)16個字節(jié)
typedef struct{
char name;
int age;
}Person;//8
typedef struct{
char name[2];
int age;
}Person;//8
typedef struct{
char name[6];
int age;
}Person;//12
P.S.①指針變量默認都要賦初值,如果沒有則為NULL,這是因為防止野指針的出現(xiàn)。
②函數(shù)中盡量不要返回指針。
動態(tài)內(nèi)存分配realloc
具體函數(shù):void *realloc(void *, size_t) 其中,第一個『void *』是指返回重新分配的內(nèi)存空間的首地址;第二個『void *』指針只想的內(nèi)存區(qū)域必須是malloc分配過的;『現(xiàn)在總共需要多少內(nèi)存空間』。這里需要注意的是,如果realloc沒有獲取到內(nèi)存空間,那么必須對之前的內(nèi)存進行釋放。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
char *name = NULL;
char temp;
int total = 0;
while (1) {
//從終端獲取一個字符
temp = getchar();
//判斷這個字符是不是回車鍵\n
if (temp == '\n') {
break;
} else{
//為這個字符添加一篇內(nèi)存空間
//判斷是不是第一次分配內(nèi)存空間
if (name == NULL) {
//第一次
name = (char *)malloc(1 * sizeof(char));
if (name == NULL) {
exit(EXIT_FAILURE);
}
} else{
//不是第一次,需要在之前的內(nèi)存空間里面添加 一個字符的空間
char *pTemp = NULL;
pTemp = (char *)realloc(name, (total+1)*sizeof(char));
if (pTemp == NULL) {
//釋放掉之前的內(nèi)存空間
free(name);
exit(EXIT_FAILURE);
}
name = pTemp;
}
//保存這個字符
*(name + total) = temp;
total++;
}
}
printf("%s\n", name);
free(name);
return 0;
}