系统相关
首页 > 系统相关> > (五)内存管理

(五)内存管理

作者:互联网

RT-thread中的头部主要信息如下

struct heap_mem
{
    /* magic and used flag */
    uint16_t magic;  
    uint16_t used;

    uint32_t next, prev;

};

初始化动态内存

在使用动态分配之前需要先初始化一块内存, 接收两个参数, begin_addr为内存起始地址, end_addr为内存终止地址.

void pt_system_heap_init(void *begin_addr, void *end_addr);
// 示例用法
    // 静态定义一块内存, 大小为HEAP_SIZE字节
    static uint8_t heap_mem[HEAP_SIZE];   
    // 将这块内存的首尾地址作为pt_system_heap_init的参数
    pt_system_heap_init(&heap_mem[0], &heap_mem[HEAP_SIZE - 1]); 

对一块用于动态分配的内存初始化后如下所示
mem_init.png

输入的参数begin_addr和end_addr可能未对齐到4字节, 因此实际使用的内存块可能比定义的要小一些.
lfree指向当前空闲可以分配的内存地址.

malloc分配内存

malloc函数在这一大块内存中寻找可用的内存, 检查头部used变量, 该块内存是否被占用, 距离下一块内存的空间是否足够等, 若都满足, 则分配使用. 下图是分配一块内存后的示意图.
malloc_first.png
成功分配一块内存后, 在其后边写入一个信息头, 并将前后内存块的next prev正确设置, lfree也指向了新的空闲内存块.

free释放内存

free函数将释放一块内存, 只是将used标记为0, 表示这块内存不再使用, 但是其内存内容不会清除.
在这里插入图片描述

为了避免越分配内存越碎片化, 在free中还检查前后的内存块是不是空闲的, 如果是空闲的则把他们合并起来形成一块大内存, 图中灰色的区域就合并到前一块内存中了.
在这里插入图片描述

realloc调整内存大小

realloc调整内存大小分为调大和调小.
对于调大的情况, 必须另外分配一块内存, 并将原来内存的数据拷贝到新分配的内存中, 然后释放掉旧内存.
在这里插入图片描述
对于调小的情况, 无需另外分配一块内存, 只需在原来的内存上分割即可.
在这里插入图片描述

标签:used,addr,管理,mem,一块,heap,内存
来源: https://blog.csdn.net/u014518456/article/details/112553516