分析测试百科网

搜索

喜欢作者

微信支付微信支付
×

AWorks编程:嵌入式C语言的内存管理(二)

2020.10.05
头像

王辉

致力于为分析测试行业奉献终身

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

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

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

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

wx_article_20190718121203_JSBH8L.jpg

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

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

wx_article_20190718121203_F2ScAe.jpg

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

3、内存泄漏

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

wx_article_20190718121204_TFitkK.jpg

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

wx_article_20190718121204_qL1vFk.jpg

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

wx_article_20190718121204_PRDGoI.jpg

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

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


互联网
仪器推荐
文章推荐