• Unix系统编程()malloc和free的实现


    尽管malloc和free所提供的内存分配接口比之brk和sbrk要容易许多,但在使用时仍然容易犯下各种编程错误。

    理解malloc和free的实现,将使我们洞悉产生这些错误的原因以及如何才能避免此类错误。

    to be continued 。。。。。。

    malloc的实现很简单。

    它首先会扫描之前由free所释放的空闲内存列表,以求找到尺寸大于或等于要求的一块空闲内存。

    (这取决于具体实现,采用的扫描策略会有所不同。例如first-fit或best-fit。)

    如果这一内存块的尺寸正好与要求相当,就把它直接返回给调用者。如果是一块较大的内存,那么将对其进行分割,在将一块大小相同的内存返回给调用者的同时,把较小的那块空闲内存块保留在空闲列表中。

    如果在空闲内存列表中根本找不到足够大的空闲内存块,那么malloc会调用sbrk以分配更多的内存。为减少对sbrk的调用次数,malloc并未只是严格按所需字节数来分配内存,而是以更大幅度(以虚拟内存页大小的数倍)来增加prgram break,并将超出部分置于空闲内存列表。

    至于free函数的实现则更为有趣。

    当free将内存块置于空闲列表之上使,是如何知晓内存块大小的?

    这是通过一个小技巧来实现的。

    当malloc分配内存块时,会额外分配几个字节来存放记录这块内存大小的整数值。该整数位于内存块 的起始处,而实际返回给调用者的内存地址恰好位于这一长度记录字节之后,如下图所示。

    image

    当将内存块置于空闲内存列表(双向链表)时,free会使用内存块本身的空间来存放链表指针,将自身添加到列表中,如下图

    image

    随着内存不断地释放和重新分配,空闲列表中的空闲内存和已分配的在用内存混杂在一起,如下图

    image

    应该认识到,C语言允许程序创建指向堆中任意位置的指针,并修改其指向的数据,包括由free和malloc维护的内存块长度、指向前一空闲块和后一空闲块的指针。辅之以之前的描述,一旦推究起隐晦难解的编程缺陷来,这无疑形同掉进了火药桶。

    例如,假设经由一个错误指针,程序无意间增加了冠于一块已分配内存的长度值,并随即释放这块内存,free因之会在空闲列表记录下这块长度失真的内存。

    随后,malloc也许会重新分配这块内存,从而导致如下场景:程序的两个指针分别指向两块它认为互不相干的已分配内存,但实际上这块内存缺相互重叠。

    至于其他出错情况则数不胜数。

    要避免这类错误,应该遵守一下原则。

  • 相关阅读:
    全排列问题(递归&非递归&STL函数)
    基于python的机器学习开发环境安装(最简单的初步开发环境)
    X分钟速成Python
    X分钟速成Python3
    Python6
    Python5
    Error[Pe020]: identifier "FILE" is undefined
    串口 ------ 硬件流控
    STM32F103 ------ 时钟配置
    git
  • 原文地址:https://www.cnblogs.com/tuhooo/p/8673366.html
Copyright © 2020-2023  润新知