动态内存管理

本文探讨了在程序运行前未知所需内存大小时,如何通过动态内存管理(malloc, calloc, realloc, free)来解决问题。重点介绍了内存泄露的原理,以及如何正确使用malloc和其相关函数来避免内存泄漏,确保程序的稳定运行。
摘要由CSDN通过智能技术生成

在正常申请内存时,所申请的内存大小都是固定的

比如说

	int a = 0;     //向内存申请四个字节的空间
	char arr[10];  //向内存申请10个字节的空间

但在一下情况下,在程序开始运行之前是不知所需的空间的大小

此时有两种方案解决这个问题

1.开辟大量的空间,使得不论程序需要多大的空间,均能够满足。

2.动态内存管理

动态内存函数

动态内存函数申请的空间是位于堆区上的

与栈区上开辟的空间有些差异

栈区上开辟的空间是会被系统自动回收的,而堆区则不然

只有当程序运行结束后,堆区上开辟的空间方会被释放

这是便出现一个问题,程序如果7*24小时运行的,不释放已经不需要的空间

变化引起一些问题

void test()
{
 int *p = (int *)malloc(100);
 if(NULL != p)
 {
 *p = 20;
 }
}
int main()
{
 test();
 while(1);
}

程序运行到while循环时,text中函数的空间以无作用,可也未释放。并且存储申请的空间地址的变量,随着函数运行的结束,已经销毁。无法得知所申请的这100个字节具体位置,程序继续运行下去,相当于内存永远的消失了100个字节,这也就是所谓的内存泄露

这也就是为什么存在释放空间函数的原因

开辟空间

malloc

函数声明

void* malloc (size_t size);

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。 

  1. 如果开辟成功,则返回一个指向开辟好空间的指针。
  2. 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
  3. 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己 来决定。
  4. 如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。

 calloc

函数声明

void* calloc (size_t num, size_t size);

函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。

与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。

realloc 

函数声明

void *realloc(void *ptr, size_t size)

 重新分配ptr指向的空间,重新分配size个字节的空间。(前提:该空间是动态开辟的)

当 str == NULL时,与malloc相似。

开辟一块大小为size个字节的空间,返回其起始地址。

当 str 不为空时,存在两种情况

当str为起始,往后的空间大小足以开辟size个字节时,便在原有的空间后追加空间

当str往后的空间不足以开辟size个字节时,realloc会在内存中寻找一适宜的空间,将原空间中存储的数据拷贝如其中,并释放原有空间。

释放空间

free函数

void free (void* ptr);

将申请的空间的地址传入free函数即可

但要注意

  • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
  • 如果参数 ptr 是NULL指针,则函数什么事都不做。

动态内存函数注意事项

1.记得判断函数释放成功开辟空间,开辟失败会返回NULL。

可以在代码中添加一部分判断,如:

	if (str == NULL)
	{
		perror("str:");
			break;
	}

2.在内存释放以后,不要再访问之前获得的地址

内存释放以后,该空间便被系统回收,再通过直接取到的地址访问,属于非负访问。

为了防止这个问题,可以在释放空间以后,将该指针置为空。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值