【问题标题】:How is malloc() allocating memory in a perforated heap?malloc() 如何在穿孔堆中分配内存?
【发布时间】:2021-10-31 03:12:51
【问题描述】:

我正在处理微控制器上 malloc () 和 calloc () 的分配。我能够直接读出我的 HEAP / STACK 所在的 SRAM,而我无法直接向自己解释的一件事让我印象深刻。

基本上在我的项目中,内存被分配了几次。所以我通过 malloc() 从地址 0x24000000 到类似 0x2407D000 的地址“划分”我的内存到各个分配的内存区域。我可以在内存中看到这一点,并使用分配的内存区域上的指针。

简单地说,这些区域看起来像:

/******************************************/
//                Region 1                //
//        0x24000000 to 0x24000540        //
//                                        //
/******************************************/
//                Region 2                //
//        0x24000548 to 0x24001598        //
//                                        //
/******************************************/
//                Region 3                //
//        0x240015A0 to 0x24076A10        //
//                                        //
/******************************************/

顺序如下:第一个分配是region 1的原因,第二个是region 2的原因,第三个是region 3的原因(内存比较大)。之后Region 2被free()清空。

现在分配了两个小内存,很容易适合前一个区域 2。我希望第一个小内存分配的地址为 0x24000550,第二个内存在之后的某个地方。但是,似乎内存是按相反的顺序分配的,因为第一个分配的小内存的地址为 0x24001590,第二个分配的小内存的地址为 0x24001570。所以我的问题是“malloc () 如何处理这个分配?我认为内存是从堆中的最低地址分配到最高地址的?”

希望你能听懂我的英文,我还是觉得有点难。 无论如何,非常感谢您的回答!

【问题讨论】:

  • "我以为内存是从堆中的最低地址到最高地址分配的?"你为什么那么想? malloc 可以以实施者选择的任何方式实施。无法保证您返回的指针,除非它指向适当数量的可用内存。
  • malloc 是一个实现细节;没有特定的理由让它按分配大小从最高到最低、最低到最高、半随机或更奇怪(但合乎逻辑)的策略工作。只要它返回一个指向可用内存的有效指针(至少是请求的大小),它就完成了它的工作。
  • 不要使用malloc,了解一下内存池。
  • 顺便说一句,你的英语很好。 :)
  • How does malloc () handle this allocation 您使用的是哪个 malloc 实现?您在哪个系统上针对哪个确切的微控制器使用了哪些编译器和选项?

标签: c memory memory-management


【解决方案1】:

我假设您在其 nano 版本中使用 newlib 标准 C 库实现。

malloc() 如何处理这个分配?

Region2 是 addedfree_list。然后在malloc() 中迭代free_listwe find a region greater then alloc_size,其中alloc_size 是请求的大小,为元数据添加空间和对齐填充。

r = free_list;
while(r) {
    int rem = r->size - alloc_size;
    if (rem >= 0) // we have enough size
    {
        if (rem >= MALLOC_MINCHUNK)
        {
            /* Find a chunk that much larger than required size, break
            * it into two chunks and return the second one */
            r->size = rem;
            r = (chunk *)((char *)r + rem);
            r->size = alloc_size;
        }
   .....

r 指向free_list 中的当前元素。 if (rem >= MALLOC_MINCHUNK) 为真,那么我们在r->size = rem;减小空闲列表中当前元素的大小 alloc_size(因为rem = r->size - alloc_size; - @987654336 @ 是我们进行分配后的剩余内存)。 然后 r = (chunk *)((char *)r + rem); 成为列表中的已分配内存块,r->size = alloc_size; 已分配大小。请注意,返回的块被 rem 偏移 - 所以它在最后。因此,free_list 中的区域确实是“从后面”拆分的。

我以为内存是从堆中的最低地址到最高地址分配的?

没有规则,也无法假设。每个实现都是不同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-26
    • 2013-02-23
    • 2021-12-15
    • 2021-01-10
    • 2020-12-14
    • 1970-01-01
    • 2012-07-28
    • 2012-10-10
    相关资源
    最近更新 更多