自定义malloc实现

时间:2014-08-20 21:36:06

标签: c++ c memory malloc free

最近我被问到一个问题,要实现一个非常简单的malloc,其中包含以下限制和初始条件。

#define HEAP_SIZE 2048
int main()
{
    privateHeap = malloc(HEAP_SIZE + 256); //extra 256 bytes for heap metadata

    void* ptr = mymalloc( size_t(750) );

    myfree( ptr );
    return 0;

}

我需要使用提供的确切空间在此处实现mymallocmyfree。 256字节很好地映射到2048位,如果分配了一个字节或者它是空闲的,我可以存储一个位数组。但是,当我与myfree进行ptr通话时,我无法分辨开始时分配了多少大小。我不能使用任何额外的位。

我似乎并不认为有办法解决这个问题,但我已经重申可以做到这一点。有什么建议吗?

编辑1:

  1. 对齐限制不存在。我以为我不会对齐任何东西。
  2. 有一个演示程序执行了一系列malloc s并释放来测试它,并且它没有任何小的内存块。但这并不能保证任何事情。
  3. 编辑2:

    文件中的指南: 关于您的代码的某些指南:

    1. 管理私有堆中的堆元数据;不要在提供的私有堆之外创建额外的链接列表;
    2. 设计mymallocmyreallocmyFree以适用于所有可能的输入。
    3. myrealloc应该像C ++库中的realloc一样执行以下操作: void* myrealloc( void* C, size_t newSize )
      1. 如果newSize大于reallocThis中的大小:
        1. 首先应该尝试分配一个大小为newSize的块,以便新块的基本指针也是reallocThis;
        2. 如果没有可用的空间来进行就地分配,它应该在不同的区域分配一块请求的大小; 然后它应该复制上一个块的内容。
        3. 如果函数未能分配请求的内存块,则返回NULL指针,并指向内存块     参数reallocThis保持不变。
      2. 如果newSize较小,realloc应缩小块的大小,并且应始终成功。
      3. 如果newSize为0,则应该像免费一样工作。
      4. 如果reallocThis为NULL,则应该像malloc
      5. 一样工作
      6. 如果reallocThis是已经释放的指针,那么它应该通过返回NULL正常失败
    4. myFree在传递已经释放的指针时不应该崩溃。

2 个答案:

答案 0 :(得分:5)

malloc实现的一种常见方式是跟踪内存分配的大小,因此free知道它们的大小是在指针返回malloc之前将字节大小存储在字节中。所以说你只需要两个字节来存储长度,当malloc的调用者请求n个字节的内存时,实际上你会分配n + 2个字节。然后将长度存储在前两个字节中,并返回一个指向刚刚存储大小的字节的指针。

对于您的算法,一般来说,一个简单而天真的实现是使用链接的空闲内存块列表来跟踪未分配的内存,这些内存块按其在内存中的位置顺序保存。要分配空间,您需要搜索足够大的空闲块。然后,您可以修改空闲列表以排除该分配。要释放一个块,您可以将其添加回空闲列表,合并相邻的空闲块。

现代标准并不是一个很好的malloc实现,但很多旧的内存分配器都是这样工作的。

答案 1 :(得分:4)

您似乎将256字节的元数据视为位图,以逐字节为基础跟踪空闲/正在使用。

我认为以下只是一种可能的选择:

我首先将2048字节堆视为每个2字节的1024“块”。这为每个块提供了2位信息。您可以将第一个视为表示该块是否正在使用,第二个表示后续块是否与当前块相同的逻辑块。

调用free函数时,使用传递的地址在位图中找到正确的起始点。然后,您将遍历将每个块标记为空的位,直到您到达第二位设置为0的位,指示当前逻辑块的结束(即,下一个2字节块不是当前逻辑块的一部分)。

[哎呀:刚刚注意到罗斯里奇在评论中已经提出了几乎相同的基本想法。]