2

我看到了这个问题,但它只是说明了我想要做什么,而不是解释如何去做。

我有一个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 的简单解决方案非常适合。

4

3 回答 3

2

关于最简单的分配器,可以这样写:

  • 初始化:current_position = my_memory + sizeof(my_memory)。根据实现的对齐要求,您可能必须确保current_position正确对齐。
  • 分配:return ((current_position - my_memory) <= size) ? 0 : (current_position -= size);。为了对齐,您可能必须先四舍五入size到某个数字的倍数。
  • 免费:什么都不做。

就是这样。显然,如果你跟注free很多,这个策略很快就会耗尽内存。所以你可以引入一个并发症:

  • 分配:增加size足够的空间以将分配的大小写入您从数组中切出的每个“块”的开头。返回一个指向大小记录末尾的指针(即可用内存的开头)。此外,请确保每个分配都足够大以包含您定义的标头结构,即使请求小于该标头结构。

您已经引入了每次分配的开销,但这允许您:

  • free:使用 header struct 将释放的块添加到某种数据结构中(继续记住大小)。

  • allocate:如果数据结构中有一个可以满足请求的分配,则返回它,否则从主数组中切出另一个切片并返回。

现在你有了一个工作内存分配器。它不是特别好用,你比最先进的技术落后了大约 60 年,所以你可能需要引入更多的复杂性。但是内存分配算法的整个历史超出了单一答案的范围。您可以从这里开始,直到您的分配器足以满足您的目的,或者您放弃并决定使用现有的库。

于 2012-12-04T17:11:18.460 回答
1

您可以在每次分配开始时将地址(在您的情况下为数组中的偏移量)保存到下一个空闲块,即您使用一些数组作为空闲块的列表。这考虑了您如何分配和查找内存块,free 比较棘手,因为当您归还内存时,您需要做的不仅仅是调整数组中的空闲偏移量,您还需要将多个空闲块合并在一起,否则您最终导致内存碎片,然后您无法分配所需大小的块。

我认为关键概念是分配的块也总是包含到下一个空闲块的偏移量,这就是你如何使用自己的数组来跟踪其中分配的内容。

于 2012-12-04T17:10:47.883 回答
1

老歌但好歌(用于描述问题的博客文章): http: //g.oswego.edu/dl/html/malloc.html

或者,如果您正在寻找打包的东西:http: //hempeldesigngroup.com/embedded/stories/memorymanager/

于 2012-12-04T17:12:33.800 回答