动态内存管理详解

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

     下图是不同类型数据在内存中的分配:

      

 上述的开辟空间的⽅式有两个特点:
空间开辟⼤⼩是固定的。
数组在申明的时候,必须指定数组的⻓度,数组空间⼀旦确定了⼤⼩不能调整
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间⼤⼩在程序运⾏的时候才能知
道,那数组的编译时开辟空间的⽅式就不能满⾜了

像上述代码中,i是机器在内存中的栈区开辟了4个字节,arr[20]是机器在内存中的栈区开辟了连续的20个字节存放。而这些大小已经被机器限制死了,无法去改变,这就很有局限性,而如果存在动态内存分配程序员⾃⼰可以申请和释放空间,就⽐较灵活了。

 二.动态内存分配的相关函数:

         这些动态内存分配的函数使用时必须包括头文件<stdlib.h>

      1.malloc:

          使用时必须包括头文件<stdlib.h>

          

这个函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针。
如果开辟成功,则返回⼀个指向开辟好空间的指针。
如果开辟失败,则返回⼀个 NULL 指针,因此malloc的返回值⼀定要做检查。
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使⽤的时候使⽤者⾃
⼰来决定。
如果参数 size 为0,malloc的⾏为是标准是未定义的,取决于编译器

      

  当这个程序运行结束时,这申请的空间会返还给操作系统。

    这时申请的内存空间太大,系统没有足够的空间。

   2.free:

      

free函数⽤来释放动态开辟的内存。
如果参数 ptr 指向的空间不是动态开辟的,那free函数的⾏为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
  上面写的代码不严谨,既没有释放申请的内存空间也没有在申请之后判断申请的空间指向的指针是不是空指针。
   所以更加严谨的写法:
    
所以总的来说malloc和free要一起出现这样才使得程序更加严谨,不会出错。

  3.calloc:

函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0

  由这两个运行结果就可以看出来malloc与calloc的区别。
   也可在调试内存中看出calloc将数组10个元素全部初始化为0.
  所以如果我们对申请的内存空间的内容要求初始化,那么可以很⽅便的使⽤calloc函数来完成任务

    4.realloc:

         

  

realloc函数的出现让动态内存管理更加灵活。
有时会我们发现过去申请的空间太⼩了,有时候我们⼜会觉得申请的空间过⼤了,那为了合理的使⽤内存,我们⼀定会对内存的⼤⼩做灵活的调整。那 realloc 函数就可以做到对动态开辟内存⼤
⼩的调整。
ptr 是要调整的内存地址
size 调整之后新⼤⼩
返回值为调整之后的内存起始位置。
这个函数调整原内存空间⼤⼩的基础上,还会将原来内存中的数据移动到新的空间。
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有⾜够⼤的空间
情况2:原有空间之后没有⾜够⼤的空间
综上两种情况下,在使用realloc时,需要注意一下,用一个临时的指针变量来存放扩展完的内存空间的地址:
  
 当给realloc传第一个参数时如果传NULL时此时的作用就跟malloc一样,会开辟一个新的内存空间。

  三.在开辟动态内存空间时容易犯的错误:

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

             

   因为没有提前进行判断p是否为空指针,所以导致调试时出现了异常。

   所以要对其做一个判断:

   此时用assert函数对其进行断言或者用if语句判断:

  

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

      

这跟数组非常相似。

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

      

当去调试的时候你会发现:

 压根没有这块内存空间去释放:

运行的时候也会卡死

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

         在前面的代码中我们利用循环去给开辟的内存空间去赋值:

       

这是一种循环的写法,还有一种:

虽然这两段代码都可以实现对其赋值但是,在代码二中p的指向不断移位,结束之后就不再是起始位置,而内存释放时要的是开辟的空间的起始位置。

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

但是如果你每次释放完内存时,都将指针置为空,此时也能正常运行。

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

     

  所以当申请完内存空间想到的第一步就是用完要释放申请的内存空间。

四.动态内存经典笔试题分析:

      1.

  图解:
    正确的写法1:
    
  正确写法二:

  2.返回栈空间指针的问题:

      

    不能返回临时变量的地址。

    可能打印出来,也可能打印不出来。

     图解:

  3.

  

     没有释放开放的内存空间,没有free,造成内存泄漏

  4.

这个题目要我们记住的也是free完之后要将其置为空指针。

五.柔性数组:

    C99 中,结构中的最后⼀个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

    根据这句话可以知道,要想使用柔性数组,则:

          1.必须在结构体中而且要是最后一个结构体成员。

          2.最后一个成员是数组,并且是没有指定这个数组的大小。

    1.柔性数组的写法:

          

     2.柔性数组的特点:

         结构中的柔性数组成员前⾯必须⾄少⼀个其他成员。

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

         • 包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该⼤于结构的⼤⼩,以适应柔性数组的预期大小。
   sizeof计算时不会包含柔性数组的大小。而且这就是为什么柔性数组前面必须要有其他的结构体成员,因为如果没有的话sizeof计算不出大小。
  

    3.柔性数组的使用:

       

    这里能使用malloc开辟空间所以也能使用realloc来开辟空间,因为前面的成员的内存空间是固定的,所以当用realloc去调整大小时,是后面数组的大小在不断变化,所以才称为柔性数组。这也就是为什么柔性数组要放在结构体成员最后。

  调整柔性数组的空间大下:

    法一:

法二:先开辟一个内存空间给结构体中的成员,再单独给结构体成员中的柔性数组再单独开一个内存空间:

 

  

上述 法 1 和 法 2 可以完成同样的功能,但是 ⽅法 1 的实现有两个好处:
第⼀个好处是:⽅便内存释放
如果我们的代码是在⼀个给别⼈⽤的函数中,你在⾥⾯做了⼆次内存分配,并把整个结构体返回给⽤
⼾。⽤⼾调⽤free可以释放结构体,但是⽤⼾并不知道这个结构体内的成员也需要free,所以你不能
指望⽤⼾来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返
回给⽤⼾⼀个结构体指针,⽤⼾做⼀次free就可以把所有的内存也给释放掉。
第⼆个好处是:这样有利于访问速度.
连续的内存有益于提⾼访问速度,也有益于减少内存碎⽚。(其实,我个⼈觉得也没多⾼了,反正你
跑不了要⽤做偏移量的加法来寻址)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/531156.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DeepStream做对象模糊的几种方法

有时候&#xff0c;我们需要对视频的敏感信息做模糊处理&#xff0c;比如模糊人脸&#xff0c;车牌。 有时候&#xff0c;也需要对整帧做模糊&#xff0c;或者遮挡。比如这个例子。 下面介绍几种模糊的办法。 1. 通过nvosd deepstream-test1是DeepStream最简单的一个例子&…

基于SpringBoot的“垃圾分类网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“垃圾分类网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统功能界面图 用户登录、用户注…

基于java+springboot+vue实现的人事管理系统(文末源码+Lw)23-242

摘 要 使用旧方法对人事管理系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在人事管理系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次开发的人事管理…

时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测

时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测 目录 时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现SSA-ESN基于麻雀搜索…

SQL 注入之 Windows/Docker 环境 SQLi-labs 靶场搭建!

在安全测试领域&#xff0c;SQL注入是一种常见的攻击方式&#xff0c;通过应用程序的输入执行恶意SQL查询&#xff0c;从而绕过认证和授权&#xff0c;可以窃取、篡改或破坏数据库中的数据。作为安全测试学习者&#xff0c;如果你要练习SQL注入&#xff0c;在未授权情况下直接去…

(2022级)成都工业学院数据库原理及应用实验一:CASE工具概念数据模型建模

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、代码仅提供参考 3、如果代码不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 PowerDesigner 16.1 实验要求 某医院一个门诊部排班管理子系统涉及如下信息&#xff1a; 若干科室&a…

传输大咖22|如何利用ProtoBuf实现高效的数据传输?

在今日信息技术日新月异的时代&#xff0c;数据传输的速度与安全性无疑成为了软件开发中的重中之重。无论是微服务架构下的服务间交流&#xff0c;还是客户端与服务器间的数据互动&#xff0c;寻求一种既高效又稳妥的数据传输方式已成为共识。尽管传统的数据格式&#xff0c;如…

论文复现 混淆矩阵

概念 参考视频&#xff1a; 使用pytorch和tensorflow计算分类模型的混淆矩阵_哔哩哔哩_bilibili 混淆矩阵是评判模型结果的一种指标&#xff0c;属于模型评估的一部分&#xff0c;常用于评判分类器模型的优劣。 准确率&#xff1a;所有预测正确的验证集样本个数/所有的验证集…

什么是SSL重签(reissue)?具体怎么做?

SSL重签&#xff08;reissue&#xff09;是指在SSL/TLS证书到期或需要更新时&#xff0c;证书持有者向证书颁发机构&#xff08;CA&#xff09;申请新的证书的过程。这通常是因为原有证书的有效期即将结束&#xff0c;或者证书因为某些原因&#xff08;如密钥泄露、证书损坏等&…

2024,嵌入式还适合入吗?为什么好多人劝退?

昨几天有个老铁找我&#xff0c;说买了我们的教程。 我有点奇怪&#xff0c;c语言教程我们都是送的。 聊了一会才知道&#xff0c;有人拿我送给粉丝的教程工具资料&#xff0c;到某宝上卖。 他就是买了资料&#xff0c;看我们的教程和经历&#xff0c;找到我的。 他说&#xff…

深入理解LRU缓存算法:原理、应用与优化

LRU算法&#xff08;Least Recently Used&#xff0c;最近最少使用算法&#xff09;的思想是基于"时间局部性"原理&#xff0c;即在一段时间内&#xff0c;被访问过的数据在未来仍然会被频繁访问的概率较高。 LRU 原理 LRU算法的主要思想是将最近被使用的数据保留在…

redis的三大模式的演化及集群模式思考和总结

redis的三大模式&#xff0c;也是循序渐进。 1、主从复制 比如一开始的读写分离的&#xff0c;主从复制。 一个master&#xff0c;多个slave。 master进行写和 增量同步&#xff0c;slave负责读&#xff0c;和接收增量同步的信息。 这样压力减轻。 2、哨兵模式 这个推出…

如何通过VPN访问内网?

VPN&#xff08;Virtual Private Network&#xff09;是一种通过公共网络建立私有网络连接的技术&#xff0c;可以在不同地点的网络中建立安全通道&#xff0c;实现远程访问内网资源的目的。本文将介绍如何通过VPN访问内网&#xff0c;并介绍一款名为“天联”的VPN服务。 什么是…

ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?

前言 ASP.NET Core 内置的标识&#xff08;identity&#xff09;框架&#xff0c;采用的是 RBAC&#xff08;role-based access control&#xff0c;基于角色的访问控制&#xff09;策略&#xff0c;是一个用于管理用户身份验证、授权和安全性的框架。 它提供了一套工具和库&…

软件设计—接口安全设计规范

1.token授权机制 2.https传输加密 3.接口调用防滥用 4.日志审计里监控 5.开发测试环境隔离&#xff0c;脱敏处理 6.数据库运维监控审计 软件项目相关全套精华资料包获取方式①&#xff1a;点我获取 获取方式②&#xff1a;本文末个人名片直接获取。

内网IP与外网IP关联关系连接过程

前言 我们每天都会访问各种各样的网站&#xff0c;比如淘宝&#xff0c;百度等等。不免会思考&#xff0c;我们的设备是如何连接上这些网址的呢&#xff1f;要想搞清楚这个问题&#xff0c;首先就得先搞清楚内网ip和外网ip的联系。 网络结构 如图&#xff0c;假设我们的计算机…

测试开发必备技能:Python多线程处理!

什么是进程 进程是执行中的程序 拥有独立地址空间&#xff0c;内存&#xff0c;数据栈等 操作系统统一管理 派生&#xff08;fork或spawn&#xff09;新进程 进程间通信&#xff08;IPC&#xff09;方式共享信息 什么是线程 同进程下执行&#xff0c;并共享相同的上下文 …

python运行报错 ModuleNotFoundError: No module named ‘speech_recognition‘解决方法

写在前面 自己的测试环境&#xff1a; Ubuntu 20.04 一、问题描述 运行 python 程序时遇到如下问题&#xff1a; Traceback (most recent call last):File "mix.py", line 10, in <module>import speech_recognition as sr ModuleNotFoundError: No module…

羊大师分享:每日一杯羊奶,健康生活我有秘诀

今天&#xff0c;我要为大家揭开羊奶那神秘的面纱&#xff0c;分享为何它被我誉为“液体黄金”&#xff0c;以及如何正确饮用。 首先&#xff0c;让我们看看羊奶为何如此独特&#xff1a; 丰富的营养&#xff1a;羊奶含有高质量的蛋白质和必不可少的氨基酸&#xff0c;它们对…

免费在线SSL证书格式转换工具,轻松完成SSL证书格式转换

在互联网时代&#xff0c;网站安全问题备受关注&#xff0c;SSL证书作为确保网站安全的重要工具&#xff0c;会部署在服务器上来实现HTTPS确保传输数据安全。然而SSL证书有PEM、JKS、PKCS等多种格式&#xff0c;市面上有Apache、Nginx、Tomcat、Windows Server&#xff08;IIS&…