当前位置:首页 > 消费电子 > 消费电子
[导读]很多工程师都知道,C/C++语言与其他语言不同,它需要开发者自己管理内存资源,动态内存使用不当,容易造成段错误或者内存泄漏,因此内存管理至关重要。本文将以C语言为例介

很多工程师都知道,C/C++语言与其他语言不同,它需要开发者自己管理内存资源,动态内存使用不当,容易造成段错误或者内存泄漏,因此内存管理至关重要。本文将以C语言为例介绍动态内存管理的原理。

C/C++语言与其他语言不同,它需要开发者自己管理内存资源。对于动态内存的使用不当容易造成段错误或者内存泄漏。尤其是内存泄漏,内存泄漏往往是在程序运行一段时间才会被发现,使得开发人员无法第一时间定位错误。

而相比于个人计算机,嵌入式系统的内存资源更是稀缺。作为嵌入式C的开发人员,了解其内存管理的原理能使其更加正确地使用内存资源以及定位程序的bug。本文将以C语言为例介绍动态内存管理的原理。

动态内存的原理

1、栈空间与堆空间

在介绍内存管理之前,我们先解释一下栈空间与堆空间:栈空间是由编译器自动分配释放,对于AWorks等操作系统,在用户创建一个任务的时候可以由自己决定任务栈空间的大小。

栈空间里面一般存放着如下数据:在函数内的局部变量(不包括static定义的变量),在调用另一个函数时保存的通用寄存器信息等。

参考如下例程(为了便于理解,省略通用寄存器等信息):

 

 

在task执行s = calculate_sum(a,b);之前,task的栈内保存如下数据:

 

 

程序接下来执行calculate_sum函数,其栈向下增长。在返回task之前,其栈结构如下:

 

 

执行完calculate_sum之后,根据返回地址返回task之后,栈恢复调用之前的结构:

 

 

所以栈空间存储着代码块内的局部变量,动态地增减着内部的数据。这也就是为什么当接口调用结束后变量就不再“生存”的原因。

堆空间是由OS管理的一片区域,开发者可向OS动态申请一片区域用于操作数据。

堆空间在程序运行时一直有效,相当于定义了一个大型的全局数组。需要时向堆空间申请内存,使用完毕再还回去。这样可以使得开发者能够动态地控制空间的大小,而不需要在写代码的时候就考虑最糟的情况(定义一个数组必须在编译之前就确定其大小,使用过程中无法增加或减少,所以必须考虑最多需要的数据大小)。

堆空间由编译器决定,如果开发者想尝试实现一片动态内存,可向堆申请一片对齐的内存空间。

2、内存资源的申请与释放

我们这里以常用的内存操作接口——malloc与free为例,介绍操作动态内存的细节。

void* malloc(size)——申请一片大小为size字节的内存。

参考下图,灰色部分是已经被使用的内存,空白部分则是可以被申请使用的内存。在申请内存的时候,系统会首先判断有没有足够大的未被使用的区域,如果有,则将其分配给申请者,再将此区域标记为“已使用”;否则分配失败。

 

 

(为方便读图,从这里开始我们假定内存的地址从上往下增长)

void free(void *)——释放已申请的内存。与malloc相反,free的作用是把“已使用”的区域标记为“未使用”,那么释放的内存下一次就可以再分配出去复用。free释放的内存必须是malloc申请的内存。

由于需要对内存进行状态标记和位置记录(以便释放)。在申请/释放内存的时候需要额外的空间进行信息的记录。有的系统会将记录的信息集中管理,有的则是申请内存的时候额外地多申请一小片区域用于记录。

3、内存泄漏

对于动态申请的内存,使用完毕之后应该还给堆,才能在后续继续分配出去。而如果申请的内存如果没有还回去,就造成了内存泄漏。参考如下一段代码:

 

 

现在我们设flag=1,执行这个函数会发生什么?

首先ptr会指向申请的128字节的内存(图b),然后判断flag==1之后再申请256字节的内存(图c)。假设我们现在使用完毕将ptr释放:

现在我们释放了256字节的内存块了,但是我们开始的时候还申请过128字节的内存块,这128字节的内存块最终会怎样呢?由当时唯一指向这块内存的指针ptr后面指向了256字节的内存块,现在没有任何指针指向这块内存,因此这一块内存再也无法被释放,这时候我们就说内存泄漏了。

在程序最开始运行的一段时间内,系统是没有异常的。即使一小片内存不被释放也不会造成错误,因为内存堆还有足够的空间可以使用。但是如果运行的时间足够长,多次调用这个函数(参数flag==1)之后,堆空间会逐渐被泄漏的内存块占满,直到程序无法再从堆里申请到内存,程序才会报错。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭