编写内存分配器
摘要用于C中的内存分配器
内存分配器101-写一个简单的内存分配器
void * malloc ( size_t size );
void free ( void * ptr );
Block * merge_blocks ( Block * block );
// the above three will be implemented first later calloc and realloc 定义数据结构:您需要一个数据结构来跟踪每个块的大小和分配状态。这可能是一个简单的结构,具有大小和标志,指示块是否免费。
初始化堆:当您的程序启动时,您需要搁置一大堆内存才能充当您的堆。可以使用mmap()系统调用来完成。
实施malloc() :此功能应找到一个足够大以满足请求的自由块。如果不存在这样的块,则应增加堆的大小。一旦找到合适的块,应将其标记为分配并返回其地址。
实现free() :此功能应将指针用于一个内存块,将其标记为免费,并有可能减小堆的大小,如果释放块在末尾。
实现realloc() :此功能应调整分配的块大小。这可能涉及找到一个新块并复制旧数据。
处理碎片:随着时间的流逝,堆可能会被散布在整个过程中的自由块变成碎片。您可能需要实施碎片堆积的策略,例如相邻的自由区。
在堆分配器的上下文中,“块”是指堆内的内存块。这就是为什么您需要它们以及它们如何工作:
为什么要阻止? :当您管理内存时,将其分为可管理的块或“块”很有帮助。每个块可以独立分配和分配。这可以有效地使用内存,因为您可以根据需要分配尽可能多的内存,而无需再分配。
块结构:每个块通常包含有关块的元数据(例如其大小以及它是免费的还是分配的)以及存储在块中的实际数据。分配器使用元数据来管理内存。
分配:当您致电malloc()时,分配器会寻找一个足够大的自由块,可以容纳所需的数据量。如果找到一个,它将标记为分配的块,并将指针返回到块的数据部分。
DealLocation :当您致电free()时,分配器将块标记为免费,使其可用于将来的分配。如果释放块位于堆的末端,则分配器还可以减小堆的大小以释放内存。
分散:随着时间的流逝,随着块的分配和划分,堆可能会破碎。这意味着将自由记忆分为小的,无连接的块。这可能使很难找到足够大的malloc()调用,即使有足够的总免费内存。为了处理这一点,分配者通常包括逻辑以碎片堆,例如相邻的自由块合并。