C语言中的内存泄漏如何解决?
ARM与嵌入式 2024-05-24
只有在堆内存里面才会发生内存泄漏的问题,在栈内存中不会发生内存泄漏。因为栈内存在自动分配空间之后,还会自动释放空间。什么是堆内存?存储方式是什么样的呢?

首先我们先来介绍一下堆内存在C代码中的存储方式。C代码中动态申请堆内存的申请函数是malloc,常见的内存代码如下图所示:

因为malloc函数返回值是一个内存地址,所以保存堆内存的变量一定得是一个指针,当然这个变量可以是一个单指针,也可以是一个多重指针。
如何获取堆内存?
对于堆内存的获取方法,我们可以有两种方法,第一种是用返回值传递内存指针,第二种方法是通过参数传递给内存指针。上面我们用到的malloc申请内存,就是属于方法一的一种具体表现形式,是直接把返回值传递给内存指针。
方法一:把函数返回值直接赋值给指针,一般表现形式如下: 方法二:将指针地址作为函数返回参数,通过返回参数保存堆内存地址,一般表现形式如下: 总结:这两类方法的本质是一样的,都是函数内存间接申请了内存,但是只有传递内存的方法不一样,方法一是通过返回值传递内存指针,方法二是通过参数传递内存指针。
内存泄漏的三个原因

当我们的代码出现内存泄漏的时候,一般都会包含以下几个原因:

  • 函数内有局部指针变量定义

  • 对该局部指针有获取内存的操作

  • 在函数返回前没有释放该内存,也未保存到其他全局变量或返回上一级函数

如何检查内存泄漏
为了避免检查内存泄漏,我们还是要养成良好的编码习惯。当我们要进行检查内存泄漏问题的时候,一般要做到以下三点:
  • 当我们在函数中看到有局部指针的时候,一定要仔细检查是否有存泄漏的问题发生,养成仔细检查的习惯

  • 如果有局部变量,并且有对局部变量赋值的操作,要检查函数的返回的指针到底是指向什么?是全局变量、静态数据还是堆内存?如果代码中有不熟悉的接口,要找到对应接口文档或源代码分析,保证不要出现不必要的错误

  • 如果函数中有对局部指针有内存申请的操作,那么要检查被保存的是全局变量吗?会被作为函数返回值吗?如果都不是的话,那要排查函数所有的“return”的地方,要保证内存被正确释放,不占用内存


声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【7.24 深圳】2025国际AI+IoT生态发展大会/2025全球 MCU及嵌入式技术论坛


  • 相关技术文库
  • C语言
  • 编程
  • 软件开发
  • 程序
  • 光立方程序编写步骤

    基于51单片机的4*4*4光立方程序实现原理及程序代码。LED光立方的复位电路、时钟电路、每层LED灯电路控制逻辑,系统总原理图,工作流程及相关C语言源码实现。希望能够对你学习了解LED光立方程序编写及LED立方实体制...

    07-04
  • 封装继承多态

    封装: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。 封装的意义: 封装的意义在于保护或者防止代码(数据)被我们无意中...

    07-04
  • 封装是什么意思?

    即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中...

    07-04
  • 超声波模块测距51程序_单片机超声波测距c语言

    超声波检测原理 超声波测距的程序流程图 程序如下: //超声波模块程序 //超声波模块程序 //Trig = P2^0 //Echo = P3^2 #include #define uchar unsigned char #define uint unsigned int // void delay(uint z) {...

    07-01
  • 大佬带你看嵌入式系统,嵌入式系统该学习什么?

    嵌入式系统是当今的热门系统之一,在诸多领域,嵌入式系统都有所应用。为增进大家对嵌入式系统的认识,小编将为大家介绍嵌入式系统是一个什么样的专业,以及学习嵌入式系统该学习哪些内容。如果你对嵌入式系统具有...

    06-27
  • c51单片机编程要点总结

    c51单片机编程要点总结 1、头文件:#include (我用的是 STC 89C54RD+) 2、预定义:sbit LED = P1^0// 定义 P1 口的 0 位为 LED 注:“P1^0”这个写法,与 A51 不同(A51 是 P1.0),P1 是一组端口,端口号范围 0~7 注2...

    06-25
  • C语言基础知识点汇总

    总结C语言基础知识点

    06-23
  • Keil使用中的若干问题

      一、混合编程  1、模块内接口:  使用如下标志符:  #pragma asm  汇编语句  #pragma endasm  注意:如果在c51程序中使用了汇编语言,注意在keil编译器中需要激活Properties中的“Generate Assembler...

    06-23
  • ESP32-finsh

    esp32c2添加finsh实现了ping指令和AT指令解析

    06-13
  • 一文讲通C语言位域,快速掌握!

    在嵌入式系统的开发中,内存是最程序员非常需要关注的对象,尤其是MCU开发、网络协议解析、硬件寄存器操作等领域,能否对内存进行高效的利用和合理的管理,将直接影响程序的性能和硬件的稳定性。

    06-10
下载排行榜
更多
评测报告
更多
广告