c语言:动态内存知识点(申请、释放、free崩溃的原因)

本文介绍了动态内存分配的基础概念,包括malloc、calloc、realloc和free等关键函数的使用方法及注意事项,探讨了内存泄漏的问题及其对程序的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态内存

用户无法确定空间大小,或者空间太大,栈上无法分配时,会采用动态内存分配,存放于堆(heap)区,不能通过变量名或数组名引用,只能通过指针引用.

1、在Windows操作系统中,堆中最大连续内存大概1.3G。

2、最大问题:内存泄漏(软件开发设计考虑的主要方面,每次泄露少量,久而久之很多,导致程序运行速度减慢甚至导致系统崩溃。)

3、内存不足时返回空指针。

4、返回类型是void*类型,表示未确定类型的指针,void*可以强转为任何其他类型指针。

5、主要函数  malloc(),  calloc(),  realloc(),  free().头文件:#include<stdlib.h>

malloc

用于申请一块连续的指定大小的内存块区域

 函数原型:void *malloc (unsign int size)

参数:size

int *p = (int*)malloc(n*sizeof(int));   //int [p]

返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象

sizeof(int)尽量不使用具体数据类型数值

原因:自定义数据类型不容易得到数值

          不同平台数值可能不同。(跨平台问题)

calloc

 calloc用于将所有元素赋值初始值为0

 函数原型:void *calloc(unsigned num,unsigned size)

参数:num(元素的数目),size(申请地址的单位元素长度)

int *p = (int*)calloc(100,sizeof(int));

 malloc和calloc之间的主要区别:calloc在返回指向内存的指针之前把它初始化为0。

没有malloc常用

realloc

调整动态内存,主要用于扩大内存

函数原型: void*realloc(void *p,unsigned int size)

参数:p(要改变内存大小的指针名),size(新的内存大小)

p = (int*)realloc(p,20*sizeof(int));

使用总结
1. realloc失败的时候,返回NULL
2. realloc失败的时候,原来的内存不改变,不会释放也不会移动

3. 如果是扩大内存,先进行判断,如果当前指针有足够的连续空间,不用重新申请内存,直接在后面附加;如果空间不够,按照新的内存大小重新在堆中申请内存,将原有数据拷贝到新内存区域,并且释放原有指针空间(注意:是自动释放,不需要使用free),同时返回新分配的内存区域首地址。

 如果它用于缩小一个内存块,原空间不变,服务器不会对此作出改变。

4. 如果size为0,效果等同于free()。这里需要注意的是只对指针本身进行释放,例如对二维指针**a,对a调用realloc时只会释放一维,使用时谨防内存泄露。
5. 传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的
6.传递给realloc的指针可以为空,等同于malloc。

free

 执行动态内存释放,防止内存泄漏内存

对于不再使用的动态分配的内存空间,可以通过内存释放free函数将其返还给堆供后续分配函数使用

 函数原型:void free(void *p)

参数:p

free(p);

通过以上的存储方式结构图可以看出有头信息和尾信息,每一段中间有空白区域,所以free 不需要长度信息。

free崩溃的原因:

  1、越界,漏写sizeof(),或者realloc()第二个参数错误。

int main()
{
	int *p1 = (int *)malloc(20);
	for(int i=0;i<20;i++)
	{
		p1[i] = 0;
	}
 
	free(p1);
	return 0;
}

  2、指针移动,找不到头(修改了指针的值)

int main()
{
	int *p = (int *)malloc(10*sizeof(int));
	for(int i=0;i<10;i++)
	{
		*p = 0;
		p++;      //不free不崩溃
	}
	free(p);     //崩溃
	return 0;
}

  3、重复释放内存

int main()
{
	int *p = (int *)malloc(10*sizeof(int));
	int *q = p;
	free(p);
	free(q);
 
	return 0;
}

  4、释放不是动态创建的内存(非动态内存)

int main()
{
	int a = 10;
	free(&a);
 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值