当前位置: 首页 > article >正文

动态内存管理(下)

1.常见的动态内存的错误

我们在学习动态内存的时候,常出现的一些错误我们来看一下。

1.对NULL指针的解引用操作

例如我们在使用malloc或者calloc开辟动态空间的时候,有时候没有判断是否开辟成功而直接对齐的返回指针进行解引用,此时如果开辟失败,返回值为空指针,此时就会出错。

演示如下:

 上述代码中我们开辟了10个整型大小的空间,并将calloc的返回值强转为int *类型的指针赋给pt,并解引用pt找到开辟的空间并赋值1,后释放空间。我们知道此处的calloc的返回值肯能为NULL,如果我们直解引用的话,编译器就会报错,free是没啥问题的,因为我们在之前学习到我们给free传NULL的话,free就不会有任何操作。

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

在之前我们学习到开辟数组又是会越界访问,那么在动态开辟空间中也会有这样的现象吗?答案肯定的。演示如下:

上述代码中我们创建了10个整型空间,并将它的返回值强转为int*类型的,我们用assert对pt进行断言,当pt为NULL时就会报错。我们运用for循环对申请的空间进行访问赋值。当我们的i为10时就会出现越界访问的问题。这是因为我们的i等于10时,就已经访问到了11个整型了。然而我们申请的空间却只有10个整型,所以会出现越界访问的问题。这种行为是十分危险的,所以我们在写代码时要小心。

3. 对非动态开辟内存使用free释放

我们在之前了解到free是专门用来释放动态空间的,那我们能用其来释放非动态空间吗?答案是不能的。演示如下:

我们看这个代码就是一个典型的例子,那么运行结果是什么呢?

我们看到编译器报错了。这就说明了free不能用来释放非动态空间。

4.使用free释放一块动态开辟内存的一部分 

我们在申请空间的时候,有时候会对指向该空间的指针进行加减,此时再对该指针进行free就会造成释放一块动态开辟内存的一部分。那么此时会出现什么问题呢?演示如下:

这个时候也会报错。free函数的参数一定是指向动态内存起始位置的地址。你也可以想想为别人借你100,你只还他20,那他肯定就会不愿意。

5.对同一块动态内存多次释放 

那我们是否可以对一个空间进行多次释放呢?我们来试一下:

很显然也不可以,这个我们也可以想成我们借别人100,结果让我还200我肯定不愿意呀。

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

我们在申请动态内存空间后却忘记释放,有时候就会导致内存泄漏,有人就会问程序结束的时候,内存不也会回收吗?那如果是死循环呢?那么程序就不会结束,动态内存也就不会回收。所以我们要注意申请动态空间也需要释放空间。

2. 柔性数组

1.什么是柔性数组

也许你从来没有听说过柔性数组(flexiblearray)这个概念,但是它确实是存在的。
C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

有些编译器会报错,就需要写成:

 

 2.柔性数组的特点

• 结构中的柔性数组成员前面必须至少一个其他成员。
• sizeof返回的这种结构大小不包括柔性数组的内存。
• 包含柔性数组成员的结用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

例如:

这里sizeof计算结构体大小时就没有算入柔性数组的大小。

 我们可以在结构体中定义一个指针,然后申请一份空间,在把这个申请的空间给这个指针让它来维护这份空间。

3.柔性数组的优势

好处1:方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
好处2:这样有利于访问速度
连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)。

谢谢


http://www.kler.cn/a/233455.html

相关文章:

  • AcWing 300 任务安排1
  • linux安装netstat命令
  • 从0开始深度学习(28)——序列模型
  • 国标GB28181视频平台EasyCVR私有化部署视频平台对接监控录像机NVR时,录像机“资源不足”是什么原因?
  • JMeter基础篇
  • [HNCTF 2022 Week1]ret2shellcode-好久不见12
  • SpringMVC第二天
  • 2024年2月5日-2月11日(全面进行+收集虚幻引擎免费资源)
  • 洛谷 P1048 [NOIP2005 普及组] 采药
  • 用python写个类
  • [BeginCTF]真龙之力
  • linux k8s 源码编译及单集群测试
  • C语言----内存函数
  • 【蓝桥杯选拔赛真题64】python数字塔 第十五届青少年组蓝桥杯python 选拔赛比赛真题解析
  • 基于微信江西南昌某汽修店保养预约小程序系统设计与实现 研究背景和意义、国内外现状
  • 探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”
  • 【flutter】报错 cmdline-tools component is missing
  • 跟着pink老师前端入门教程-day23
  • k8s的Deployment部署策略线上踩坑
  • 论文精读的markdown模板——以及用obsidian阅读网页资料做笔记
  • 4核8g服务器能支持多少人访问?2024新版测评
  • 简单的Udp服务器
  • 人类的控制不同于机器的控制
  • MySQL篇之回表查询
  • SegmentAnything官网demo使用vue+python实现
  • LLaMA 2 和 QianWen-14B