【C语言】动态内存管理

什么是动态内存?

void fun()
{
	char strb[1024 * 1024] = {0};
}

int main()
{
	char stra[1024 * 10] = {0};
	fun();
	return 0;
}

运行时程序崩溃,这是为什么呢?
在这里插入图片描述
分析编译链接过程,我们知道栈区在函数被调用时分配,用来存放函数的参数值,局部变量等。在window中栈的默认大小时:1M,在visual studio中我们可以设置栈区的大小,在Linux中栈的默认大小为10M,在gcc编译时可以设置栈区的大小。
堆区:程序运行时可以在堆区动态的请求一定大小的内存,并在用完之后归还给堆区,在Linux系统中堆区的大小一般接近3G。
因此当我们需要大块内存或程序在运行过程中才知道所需内存的大小,我们就从堆区分配空间。
在这里插入图片描述

动态内存分配函数

malloc

向堆区申请一块指定大小的连续内存空间

void* malloc(size_t size);
typedef unsigned int size_t;

size: 要分配的字节数
分配成功:返回指向新分配内存的指针,为避免内存泄漏,必须要用free()释放分配的空间。
失败:返回空指针

void free(void* ptr);
int main()
{
	int n = 0;
	int i = 0;
	int *ip = NULL;
	scanf("%d",&n);
	ip = (int*)malloc(sizeof(int)*n);
	if(NULL == ip) exit(1);
	for(int i = 0;i < n;i++)
	{
		ip[i] = i + 10;
	}
	free(ip);//空悬指针
	ip = NULL;
	return 0;
 }

free之后一定要将指针置空,因为当我们把指针指向的堆空间释放之后,指针就变成失效指针,依旧指向哪里,当我们重新申请堆区空间,进行使用的时候,旧指针会影响新申请的堆空间。
对同一个空间只能释放一次
在这里插入图片描述

calloc

分配并使用零初始化连续内存空间

void* calloc(size_t num,size_t size)

num : 元素数目
size:每个对象元素的大小
分配成功:返回指向新分配内存的指针。
失败:返回空指针

int main()
{
	int n = 0;
	int *ip = NULL;
	scanf("%d",&n);
	ip = (int*)calloc(n,size(int));
	if(NULL == ip) exit(1);
	free(ip);//空悬指针
	ip = NULL;
	return 0;
}

在这里插入图片描述
自实现calloc函数。

void my_calloc(size_t num,size_t size)
{
	void* vp = malloc(num * size);
	if(NULL != vp)
	{
		memset(vp,0,num * size);
	}
	return vp;
}

realloc

我们使用malloc或calloc申请了堆空间内存,但是在程序运行的过程中发现空间申请少了或者多了如何处理?
realloc:扩充之前分配的内存块

void *realloc(void *ptr,size_t new_size);

ptr:指向需要重新分配的内存区域的指针
new_size:数组的新大小
realloc函数调整内存大小分为三种情况:
1、后续未分配内存空间足够大,可以分配空间
在这里插入图片描述
2、后续未分配内存空间不足够大,不能分配空间
在这里插入图片描述
3、堆内存不足,扩展空间失败,realloc函数返回空。

free

int main()
{
	int n = 10;
	int *ip = (int*)malloc(sizeof(int) * n);
	if(NULL == ip) exit(1);
	for(int i = 0;i < n;i++)
	{
		ip[i] = i;
	}
	ip += 5;
	free(ip);
	return 0;
}

在这里插入图片描述
当我们用malloc申请了多少个字节,就要用free释放多少个字节,当用malloc申请空间时,我们会和free达成一个协议,申请空间时,会有一个头部信息,它会记录申请空间的字节个数,free就会按申请的字节个数进行释放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值