C++ 自定义malloc实现

C++ 自定义malloc实现,c++,c,memory,malloc,free,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; } 我需要在这里使用提供的确切

最近,有人问我一个问题,要实现一个非常简单的
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;

}
我需要在这里使用提供的确切空间实现
mymalloc
myfree
。256字节很好地映射到2048位,我可以用一个位数组来存储一个字节是分配的还是空闲的。但是,当我用
ptr
myfree
电话时,我不知道一开始分配了多少大小。我不能使用任何额外的位

我似乎不认为有什么办法可以解决这个问题,但有人一再重申,这是可以做到的。有什么建议吗

编辑1:
  • 对齐限制不存在。我想我不会把任何东西对齐
  • 有一个演示程序,它做了一系列的malloc和frees来测试这个,它没有任何小的内存块。但这并不能保证什么
  • 编辑2: 文件中的指南: 有关代码的某些准则:

  • 管理私有堆中的堆元数据;不要在提供的私有堆之外创建额外的链表
  • 设计
    mymalloc
    myrealloc
    myFree
    以适用于所有可能的输入
  • > MyReLoC/应在C++库中执行如下的代码,如<代码> ReLoCu:
    void*myrealloc(void*C,大小\u t新闻大小)
  • 如果
    newSize
    大于
    reallocThis
    中的区块大小:
  • 它应该首先尝试在适当的位置分配一个大小为
    newSize
    的块,以便新块的基本指针也是
    reallocThis
  • 如果没有可用空间进行就地分配,则应在不同区域分配请求大小的块; 然后它应该复制上一块的内容
  • 如果函数未能分配请求的内存块,则返回一个
    NULL
    指针,该内存块指向 通过参数
    reallock,此
    保持不变
  • 如果
    newSize
    较小,
    realloc
    应缩小块的大小,并且应始终成功
  • 如果
    newSize
    为0,它应该可以像free一样工作
  • 如果
    reallocThis
    为空,则其工作方式应类似于
    malloc
  • 如果
    reallocThis
    是已经释放的指针,那么它应该通过返回NULL正常地失败
  • myFree
    在传递已释放的指针时不应崩溃

  • malloc实现跟踪内存分配大小的一种常见方法是
    free
    在指针返回之前,通过
    malloc
    将大小存储在字节中。因此,假设您只需要两个字节来存储长度,当
    malloc
    的调用者请求
    n
    字节的内存时,您实际上分配了
    n+2
    字节。然后将长度存储在前两个字节中,并返回一个指向刚刚超过存储大小的字节的指针

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


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

    您似乎认为256字节的元数据是一个位图,可以逐字节跟踪空闲/正在使用的数据

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

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

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


    [OOP:注意到Ross Ridge在评论中已经提出了几乎相同的基本思想。[

    <代码> int()/<代码>,而不是<代码>无效()/代码>。您想用C编写它,在C和C++中使用它?这里缺少一些信息。堆的预期性能如何?它应该能够满足2048个1字节的分配吗?与其跟踪每个字节,不如跟踪每个分配。(如果元数据空间中没有足够的空间容纳另一个分配跟踪结构,只需在malloc上返回null即可。)@shrinidhisondur:最好将相关部分复制/粘贴到问题中。其他任何东西(链接)都可能导致链接在将来消亡。请怀疑256位(至少2048位)的元堆大小意味着使用2048位标志来表示分配的字节。但是我喜欢链接列表的大小,其中的块被切掉成HEAP_size/256块。耶,我不知道讲师对算法的设想是什么。对于我来说,一个免费的位图和关于分配的任何其他信息都不会产生明显更好的实现,这一点并不明显。或者甚至工作,您需要在其他地方存储分配的长度。可能有一个粒度为两个字节的位图。每对字节使用两位。一位用于记录字节对是否已分配,第二位用于标记分配的开始。但每个块的额外字节是元数据,因此元数据总量为p