C语言:动态内存管理

一.为什么存在动态内存分配

我们已经掌握的内存开辟方式有:

int val = 20;//在栈空间上开辟四个字节
char arr[10] = {
   0};//在栈空间上开辟10个字节的连续空间

但是上述的开辟空间的方式有两个特点:

  1. 空间开辟大小是固定的。
  2. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。

但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,有时候我们需要内存空间扩大或者缩小,这时候我们只能使用动态内存开辟了

比如说,之前我写的通讯录一次开辟了1000个数据空间,但我可能只需要3个人,所以其他的空间就会浪费,我们要是能随时改变开辟空间的大小,就可以让空间不再浪费,而我们开辟的动态内存,是在堆区上进行的
在这里插入图片描述







二.动态内存函数的介绍

1.malloc

void* malloc (size_t size);

头文件:<stdlib.h> 或<malloc.h>

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

1.如果开辟成功,则返回一个指向开辟好空间的指针。
在这里插入图片描述


2.如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
这里利用INT_MAX值超大的特性,向系统申请开辟一块超大的内存,系统发现没有这么大的空余空间,就会开辟失败,返回NULL
在这里插入图片描述


3.返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
在这里插入图片描述


4.如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。
size为0,可以返回地址,但是地址不能解引用去使用,即使编译器可以去使用,也不要去使用,因为该地址中的内存空间为0,你去使用会出现非法访问的问题




2.free

void free (void* ptr);

头文件:<stdlib.h> 或 <malloc.h>

功能:free函数用来释放动态开辟的内存

1.如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
free经常配合malloc去使用,当malloc开辟玩内存并进行完操作后,就要去释放开辟的动态内存
在这里插入图片描述


2.如果参数 ptr 是NULL指针,则函数什么事都不做。




3.如果我们不释放动态内存申请的内存的时候,如果程序结束,动态申请的内存由操作系统回收,如果程序不结束,动态内存是不会自动回收的,就会造成内存泄漏

假如我们有一个程序7*24小时跑在服务器里,如果有程序会慢慢吃内存,内存早晚会被侵蚀完,早晚会被泄漏完,到时候服务器里没有内存可用,服务器就会崩掉
在这里插入图片描述





3.calloc

void* calloc (size_t num, size_t size);

头文件:<stdlib.h> 或<malloc.h>

功能:这个函数向内存申请 num 个大小为 size 的元素个内存空间,并且把空间的每个字节初始化为0,返回指向这块空间的指针

1.函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
在这里插入图片描述
所以如何我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务。




4.realloc

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

头文件:<stdlib.h> 或<malloc.h>

功能:增加或减少内存空间原有的大小,使内存管理更加灵活
realloc函数的出现让动态内存管理更加灵活有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。

ptr 是要调整的内存地址
size 调整之后新大小,也就是整块内存增加后的总大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间

realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
1.扩展空间
2.返回新空间
情况2:原有空间之后没有足够大的空间,扩展的方法是:在堆空间上另找一个合适大小
的连续空间来使用。这样函数返回的是一个新的内存地址。

1.找到足够大的空间
2.拷贝原有内容
3.free掉原空间
4.返回新空间地址
>在这里插入图片描述

realloc有可能找不到合适的空间来调整大小,这是就会返回空指针
如果出现了这种情况,又用的原有指针去接受的realloc返回的空指针,原有空间就会出现泄漏,你无法再找回原有空间了,为了避免出现这种情况,我们可以创建一个临时的指针去接受,检验一下realloc是否找到了合适的空间
在这里插入图片描述

realloc单独使用也会有malloc的效果
这里的realloc的功能类似于malloc,就是直接在堆区开辟40个字节
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值