我看到了这个问题,但它只是说明了我想做什么,而不是解释如何做
我有一个C
库,它将在支持动态内存分配的系统和不支持的系统上运行。我想通过编写自己的malloc
函数来简化系统之间的转换,该函数在堆不可用时从静态数组中分配内存。
我并不是在寻找一个完全充实的解决方案来解决我的问题,但一篇带例子的博客文章会很有帮助。确定何时以及何时不使用malloc
是很容易的。但是我花了一些时间来弄清楚如何从静态数组中分配内存。
static char my_memory[10000] = { 0 };
static void *my_malloc(size_t size) {
// Here, I want to allocate 'size' in 'my_memory'.
return NULL;
}
static void *my_free(void* memory) {
// Here, I want to free 'memory' from 'my_memory'.
}
编辑:
我的需求非常简单,而且很少有内存以这种方式分配(而且很少释放)。Steve Jessop的简单解决方案非常适合。
关于可以编写的最简单的分配器:
- init:
current_position = my_memory + sizeof(my_memory)
。根据实现的对齐要求,您可能必须确保current_position
正确对齐 - 分配:
return ((current_position - my_memory) <= size) ? 0 : (current_position -= size);
。为了对齐,您可能必须先将size
四舍五入到某个数字的倍数 - free:什么都不做
就是这样。很明显,如果你经常调用free
,这个策略就会很快耗尽内存。所以你可以引入一个复杂的东西:
- allocate:将
size
增加足够的空间,以便将分配的大小写入从数组中分割出的每个"块"的开头。返回一个指向大小记录末尾(即可用内存的开头)的指针。此外,确保每个分配都足够大,可以包含您定义的头结构,即使请求的值小于这个值
您引入了每次分配的开销,但这允许您:
-
free:使用头结构将释放的块添加到某种数据结构中(继续记住大小)。
-
allocate:如果数据结构中有一个分配可以满足请求,则返回它,否则从主数组中切下另一个切片并返回它。
现在您有了一个工作内存分配器。它的效果不是特别好,你已经落后于最先进的技术大约60年了,所以你可能需要引入更多的复杂性。但内存分配算法的整个历史都超出了单一答案的范围。您可以从这里开始,直到您的分配器达到您的目的,或者您放弃并决定使用现有的库。
您可以在每次分配开始时保留下一个可用块的地址(在您的情况下是数组中的偏移量),即您使用一些数组作为可用块的列表。这考虑到了如何分配和查找内存块,空闲更为棘手,因为当你归还内存时,你需要做的不仅仅是调整数组中的空闲偏移量,你还需要将多个空闲块合并在一起,否则你最终会出现内存碎片,无法按需大小分配块。
我认为关键的概念是,分配的块也总是包含到下一个空闲块的偏移量,这就是你如何使用自己的数组来跟踪其中分配的内容
一个老掉牙的东西(用于描述问题的博客文章):http://g.oswego.edu/dl/html/malloc.html
或者,如果你正在寻找包装好的东西:http://hempeldesigngroup.com/embedded/stories/memorymanager/