C语言(长期更新)第21讲:动态内存管理

C语言(长期更新)第21讲

动态内存管理

++跟着潼心走,轻松拿捏C语言,困惑通通走,一去不回头~欢迎开始今天的学++ ++习内容,你的支持就是博主最大的动力++ 。博主主页:潼心1412o-CSDN博客


目录

C语言(长期更新)第21讲

动态内存管理

知识回顾

[21.1 为社么要有动态内存分配](#21.1 为社么要有动态内存分配)

[21.2 动态内存分配的函数](#21.2 动态内存分配的函数)

[21.2.1 malloc和free](#21.2.1 malloc和free)

[21.2.2 calloc和realloc](#21.2.2 calloc和realloc)

[21.3 常见错误](#21.3 常见错误)

[21.4 动态内存经典笔试题](#21.4 动态内存经典笔试题)

[21.5 柔性数组](#21.5 柔性数组)

[21.5.1 柔性数组的特点](#21.5.1 柔性数组的特点)

[21.5.2 柔性数组的使用](#21.5.2 柔性数组的使用)

[21.5.3 柔性数组的优势](#21.5.3 柔性数组的优势)

[21.6 总结C/C++中程序内存区域划分​编辑](#21.6 总结C/C++中程序内存区域划分编辑)


知识回顾

++上节课我们学习了联合和枚举,今天我们来学习动态内存管理,坐稳了,我们发车,gogogo,出发喽!++


21.1 为社么要有动态内存分配

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

上述内存开辟空间的方式有两个特点

空间开辟大小是固定的

数组在声明时,必须指定数组长度,数组空间一旦确定就大小不能调整

但是对于空间的需求,上述情况远远不能满足

又是我们需要的空间大小在程序运行时才能知道,那数组编译时开辟空间的方式就不能满足了

21.2 动态内存分配的函数

21.2.1 malloc和free

C语言提供了一个动态内存开辟的函数叫做malloc

m即memory内存,alloca即allocate开辟的意思

想内存申请一块连续可用的空间,并但会指向这块空间的指针

开辟失败,会返回NULL空指针,所以malloc的返回值一定要检查

返回值类型为void* ,具体使用时需强转为需要的类型

若参数为0,malloc的行为是标准未定义的

free用于做动态内存的释放和回收的

若参数ptr指向的空间不是动态内存开辟的,那么free函数行为是未定义的

ptr指向的是NULL,free啥也不做

malloc和free都声明在stdlib.h头文件中

写free是主动释放内存空间,但是没写的话,程序运行结束,操作系统会主动回收这些空间

21.2.2 calloc和realloc

calloct和malloc的功能很像,都是开辟动态内存,原型如下

不同的是,这个calloct是两个参数,在使用上

还有一点不同的是,calloc会对开辟的内存空间进行初始化,初始值全为0

malloc就不会,全是随机值

所以如果我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务

下面介绍一个函数realloc,让动态内存管理更加灵活

当我们申请的内存空间不是很合理时,就需要重新申请

那我前面申请内存空间的数据也不能丢啊,这就需要realloc对动态开辟内存大小进行调整

ptr 是要调整的内存地址

size 调整之后新大小

返回值为调整之后的内存起始位置。

这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间

当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。

当是情况2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找⼀个合适

大小的连续空间来使用。这样函数返回的是⼀个新的内存地址。

再有情况3,找不到合适的空间,内存开辟失败,返回NULL

所以在使用时,也需要注意

21.3 常见错误

对NULL指针的解引⽤操作

对动态开辟空间的越界访问

对⾮动态开辟内存使⽤free释放

使⽤free释放⼀块动态开辟内存的⼀部分

对同⼀块动态内存多次释放

动态开辟内存忘记释放(内存泄漏)

忘记释放不再使⽤的动态开辟的空间会造成内存泄漏。

切记:动态开辟的空间⼀定要释放,并且正确释放。

21.4 动态内存经典笔试题

题目一

怎么会是0呢

注意这里虽然传的是指针,却是传值调用,不是传址调用

正确写法应该是

题目二

题目三

21.5 柔性数组

21.5.1 柔性数组的特点

结构体最后一个元素,未知大小的数组,称作柔性数组(flexible array)

注意结构体除了柔性数组之外一定要有其他成员

要不然结构的大小是不确定的

sizeof 返回的这种结构⼤⼩不包括柔性数组的内存

包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该⼤于结构的

大小,以适应柔性数组的预期⼤⼩

21.5.2 柔性数组的使用

21.5.3 柔性数组的优势

⽅便内存释放

如果我们的代码是在⼀个给别⼈⽤的函数中,你在⾥⾯做了⼆次内存分配,并把整个结构体返回给⽤⼾。⽤⼾调⽤free可以释放结构体,但是⽤⼾并不知道这个结构体内的成员也需要free,所以你不能指望⽤⼾来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返回给⽤⼾⼀个结构体指针,⽤⼾做⼀次free就可以把所有的内存也给释放掉

有利于访问速度

连续的内存有益于提⾼访问速度,也有益于减少内存碎⽚

扩展阅读:C语言结构体里的成员数组和指针 | 酷 壳 - CoolShell

21.6 总结C/C++中程序内存区域划分


++好了今天的学习内容就到这里啦,谢谢你的陪伴,我是潼心,下次再见~如果这篇文章对你有帮助的话。请务必给主播一个一键三连,球球了,这对主播很重要~++

博主主页:潼心1412o-CSDN博客

相关推荐
JAVA学习通2 小时前
微服务项目->在线oj系统(Java-Spring)----6.0
java·开发语言·spring
racerun3 小时前
CSS Display Grid布局 grid-template-columns grid-template-rows
开发语言·前端·javascript
袁煦丞 cpolar内网穿透实验室3 小时前
Remote JVM Debug远程给Java程序“做手术”!cpolar内网穿透实验室第626个成功挑战
java·开发语言·jvm·远程工作·内网穿透·cpolar
2301_764441333 小时前
使用python的加权Jaccard分析流程
开发语言·python
超级大福宝3 小时前
使用 LLVM 16.0.4 编译 MiBench 中的 tiff-v3.5.4 时遇到编译链接错误
c语言·c++
埃伊蟹黄面3 小时前
STL 容器 --- list 类
开发语言·c++·list
大飞pkz3 小时前
【设计模式】单例模式
开发语言·单例模式·设计模式·c#·单例模式懒汉式·单例模式饿汉式
IOsetting3 小时前
VSCode C/C++ 开发环境配置
c语言·c++·vscode
老任与码3 小时前
责任链模式
java·开发语言·责任链模式