目录
malloc calloc realloc free(必须使用stdlib.h头文件)
动态内存 内存申请 释放流程
malloc calloc realloc
malloc: malloc 申请内存无初始值 堆内申请内存 赋初始值一般用memset
int n;
int *p=(int*)malloc(sizeof(int)*n);
assert(p!=NULL);
memset(p,0,sizeof(int)*n);
free(p);
p=NULL;
memset用法:
memset (初始化内存(void*),value(值),size_t(初始化多少个字节的内存)) memset(p,0,sizeof(int)); 0000 0000 0000 0000
memset(p,1,sizeof(int)); 0001 0001 0001 0001
申请的内存空间按字节为单位,int value 初始化
calloc:calloc=malloc+memset; calloc=malloc+for循环
int *p=(int*)calloc(10,sizeof(int))//10个整形 存在默认值初始化
realloc:扩容 必须在堆上进行操作,已经申请的内存上进行操作
realloc(p,15*sizeof(int))//内存为申请后的总内存 将p的内存扩充为15 在已有的堆内存基础 上进行扩容。
realloc扩容的三种方式
1)内存不够扩容失败
2)堆内存足够,后续足够直接在其后进行扩容
3)后续不够,另外开辟内存,能存放总数据,系统回自动将原内存内的数据移动到新开辟的内存中
int *p=(int*)malloc(100);
assert(p!=NULL);
memset(p,0,100);//100个字节初始化
int*q=(int*)realloc(p,200);
assert(q!=NULL);//debug assert 有用 release 失效
if(q==NULL) {
free(p);
p=NULL};
else {
p=q;
free(p);
p=NULL;
}
动态内存 内存申请 释放流程
释放内存只能在堆进行释放
free 出现崩溃 情况 :
1)int*p=(int*)malloc(100); free(p); free(p);
2)free(野指针)
3)int a=0; int* p=&a; free(p);//崩
free 必须在堆上进行操作,而a在栈上 free必须与malloc calloc realloc 搭配使用
/free (NULL)不会出现崩溃 参数安全检测
/int *p=&a;p=NULL;*p=10; 对空指针进行解引用必然会崩溃
例题练习:1)
此处错误之处在于free释放的地方为栈上,而栈上的内存不能释放,只能释放堆上的内存且只能与malloc calloc realloc 连用。
2)
释放之后的内存便没有了的使用权限,即释放之后便成为了悬挂指针(野指针),不能使用
3)
此处的ip自增之后便不在动态建立的内存上,所以没有释放的能力,此处错误
4)
此处没有释放堆上建立的内存,因为在函数调用完之后在后面的for循环结束,使得函数结束不了,无法释放内存,造成内存泄漏(占用内存无法使用);
5)
在函数调用时使用形参p指向了cp,p指向动态建立的内存,因为p是形参,然后再函数调用完成之后便释放函数的所有东西,导致p被删了,所以建立的内存无法使用造成了内存泄漏,
纠正:1)用int 定义调用的函数,返回p指针,这样便可以使得p指向的内存用p释放。
2)利用二级指针,将cp的地址传给p,堆p进行解引用指向新建的内存,这样函数结束之后,就算p被释放,也可以使用cp本身对堆进行内存的释放。