知识点一:malloc函数和free函数
malloc函数
头文件:#include<stdlib.h>#include<string.h> // 用于memset函数的头文件
void *malloc(unsigned int num_ size);
形参: num_ size需要申请空间大小的字节数。
返回值:成功:返回空间的起始地址失败: NULL
特点:1、对于malloc的返回值一般要强制类型转换再赋值保存(返回值就是开辟对应的空间)2、malloc申请的空间内容不确定一般使用memset进行清空3、多次调用malloc第1次malloc 和 第2次malloc的地址不一定连续
free函数
void free(void *addr); ()里面是保存malloc保存返回值的指针变量名
//功能:释放堆区空间
#include<stdio.h>
void test1()
{int *addr = NULL;addr = (int *)malloc(sizeof(int)); // (强转类型 *)malloc(n * sizeof(类型)) n:无符号整数 ()里面的字节数是n乘类型的字节数if(addr == NULL){printf("malloc err\n");}printf("*addr = %d\n",addr); //不确定值 //对堆区空间清零memset(addr,0,sizeof(int));printf("*addr = %d\n",*addr);//对addr的空间 进行读 写*addr = 1000; //写//读printf("*addr = %d\n",*addr); //1000//释放堆区空间 空间使用权限的回收是否对空间内容清0这是不确定的free(addr);
}
int main(int argc,char *argv[])
{test1();
}
知识点二:calloc函数
头文件:#include<stdlib.h>
void * calloc(size_t nmemb,size_ t size); // (强转类型 *)calloc(n,sizeof(类型)) n:无符号整数 ()里面的字节数是n乘类型的字节数
参数:1、nmemb中请的数据块数2、size 每一块大小3、申请总大小 = nmemb*size
返回值:成功:返回空问的起始地址失败:返回NULL
特点:申请的空间自动清零,不需要memset清零
知识点三:realloc动态追加或减少空间
#include<stdlib.h>
void* realloc(void *S,unsigned int newsize); //(强转类型 *)realloc(保存原先开辟内存的指针名,(原先空间+新增空间)sizeof(类型))
参数: s:原先开辟内存的首地址newsize: 新申请的空间的总大小(原先+新增部分大小)(如果新申请的空间比原先大,则是追加,如果比原先小,则是减少)
返回值:新申请的内存的首地址
realloc的返回值一般要强制类型转换再赋值保存(返回值就是开辟对应的空间)
功能:
在原先s指向的内存基础.上重新申请内存,新的内存的大小为new_ size 个字节,如果原先内存后面有足够大的空间,就追加,如果后边的内存不够用,则relloc函数会在堆区找一个newsize个字节大小的内存申请,将原先内存中的内容拷贝过来,然后释放原先的内存,最后返回新内存的地址
知识点四:堆区空间使用的注意事项
void test1()
{int *p2 = NULL;int *p3 = NULL;//1、指向堆区空间的指针变量不要随意的更改指向int *p=(int *)calloc(1, sizeof(int)) ;int num = 10;p = # //p指向num导致calloc申请的空间泄露//2、不要操作已经释放的空间p2 = (int *)calloc(1,sizeof(int));*p2 = 1000;//释放该空间free(p2) ;printf("*p2 = %d\n,*p2); //不确定//3、不要对堆区空间重复释放p3 = (int *)calloc(1, sizeof(int));free(p3);free(p3);//多次释放
}
知识点五:防止多次释放
void test09 ()
{int *p=(int *)calloc(1,sizeof(int));if(p != NULL) //防止多次释放{free(p);p=NULL;}if(p != NULL) {free(p);p=NULL;}
}