C语言(长期更新)第21讲
动态内存管理
++跟着潼心走,轻松拿捏C语言,困惑通通走,一去不回头~欢迎开始今天的学++ ++习内容,你的支持就是博主最大的动力++ 。
博主主页:潼心1412o-CSDN博客
目录
[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博客