二、動態內存分配與使用,動態內存分配使用
1.malloc
(1)malloc分配函數:需要給出申請空間大小(以字節為單位)
(2)返回值是一個首地址,用指針接收
(3)使用sizeof計算元素大小
(4)使用malloc函數申請內存空間,用完後需要釋放,否則會造成內存洩露
(5)釋放函數free需要指向分配內存的指針
(6)基本形式:void *malloc(unsigned int size);
(7)分配指定大小的內存空間,但是不會把分配的空間清0
(8)free(指針);//釋放堆空間,標記刪除,不清楚內容
(9)示例:
①malloc與一維數組
《1》去*加方括號,指針,數組兩變換,無論幾維數組,幾個*都可以
《2》隨機生成10個整數,保存到堆區
int *parr = malloc(sizeof(int) * 10);//在堆區開辟10個整型的空間
for(int i = 0 ; i < 10 ; i ++){
parr[i] = arc4random()%(100 - 10 + 1) + 10;//生成10個【10,100】的隨機數
}
for(int i = 0 ; i < 10 ; i ++){
printf(“%d “,parr[i]);//輸出
}
printf(“\n”);//換行
free(parr);//釋放申請的空間
②malloc與二維數組
《1》分配2行三列的二維數組
《2》int (*pa)[3] = malloc(sizeof(int)*2*3);
int (*pa)[3] = malloc(sizeof(int) * 2 * 3);//開辟一個2行3列的整型空間
pa[0][0] = 1;//賦值
pa[0][1] = 13;
③malloc與字符串
《1》將字符串“Hello,Lanou”保存到堆區
方案一:
char *pst = malloc(sizeof(char) * 12);//開辟12個char型空間,注意字符串結尾的\0
strcpy(pst,”Hello,Lanou”);//拷貝字符串
printf(“%s\n”,pst);//輸出
free(pst);//釋放內存
方案二:
char a[] = “Hello,Lanou”;//在棧區拷貝常量區的字符串
char *ps = malloc(sizeof(a));//開辟該字符串大小的空間
strcpy(ps,a);//將棧區的字符串拷貝到堆區
free(ps);//釋放內存
④malloc與字符串數組
《1》char (*p)[255] = malloc(5 * 255);//開辟5個字符串,每個字符串255字節的空間
《2》strcpy(p[0],”iPhone”);//拷貝字符串到第一個字符串數組
⑤malloc與結構體
typedef struct person{//創建一個有2個元素的結構體
char name[20];
int age;
}Person;
方案一:
int main(){
Person *pp = malloc(sizeof(Person));//開辟一個該結構體大小的空間
strcpy(pp->name,”六娃”);//字符串拷貝,賦值
printf(“%s\n”,pp->name);//輸出
pp->age = 34;//整型賦值
printf(“%d\n”,pp->age);//輸出
free(pp); //釋放內存
}
方案二:
《根據結構體可以直接賦值的特點》
Person p = {“貝爺”,20};//先給結構體賦初值
Person *pi = malloc(sizeof(Person));//開辟一個該結構體大小的空間
*pi = p;//直接把棧區的結構體的所有值拷貝給堆區的pi
⑥malloc與結構體數組
《1》指針用箭頭,結構體數組用點
《2》3個元素的結構體數組
方案一:
Person *pt = malloc(sizeof(Person) * 3);//開辟3個該結構體大小的空間
strcpy(pt[0].name , “Lanou”);//((pt + 0) ->name),字符串拷貝
pt[0].age = 10;//給該結構體數組的第一個結構體的一個元素賦值
printf(“%s\n”,pt[0].name);//輸出
free(pt);//釋放內存
方案二:
Person pt[3] = {{“erdanzi”,23},{“bee”,20},{“liuwa”,30}};
Person *pp = malloc(sizeof(Person) * 3);
for(int i = 0 ; i < 3 ; i ++){
pp[i] = pt[i];//結構間可以直接賦值
}
for(int i = 0 ; i < 3 ; i ++){
printf(“%s %d\n”,pp[i].name,pp[i].age);
}
free(pp);//釋放內存
2.其他內存分配函數
①calloc
《1》void *calloc(unsigned n , unsigned size);
《2》使用free釋放
《3》分配n個size大小的空間
《4》與malloc不同的是calloc申請的內存空間會初始化成0
《5》不建議使用,容易造成訪問越界。C語言沒有越界保護,程序員需要自己檢查越界
②realloc
《1》void *realloc(void * , unsigned newSize)
《2》使用free釋放
《3》按給定的地址以及給定的大小重新分配
《4》從小到大,數據不會丟失
《5》從大到小,數據可能會丟失
示例:
//原來分配的空間
int *p = malloc(100);
//重新分配的空間
p = realloc(p,150);
3.內存操作函數
①meset
《1》void *memset(void *s , int c , size_t n);
《2》不僅用於堆區,也用於棧區
《3》s開始,長度為n的所有字節賦值為c
《4》通常用於清除結構體或者數組數據
②memcpy
《1》void *memcpy(void *dest , const void *source , size_t n);
《2》從source拷貝n個字節到dest中
《3》不僅用於堆區,也用於棧區
③memcmp
《1》int memcmp(const void *buf1 , const void *buf2 , unsigned int count)
《2》內存比較,比較結果分為>0 , <0 , =0
《3》既可以用於堆內存,也可以用於棧內存