【问题标题】:Allocate static memory (as malloc replacement)分配静态内存(作为 malloc 替换)
【发布时间】:2012-11-22 08:35:41
【问题描述】:

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

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

【问题讨论】:

  • 这听起来是个坏主意。几乎总是,不“支持动态内存分配”的系统出于肯定的原因这样做,因为他们不希望暴露于不正确的内存管理可能导致的错误。复制一个动态内存管理器(恕我直言,尤其是如果你还不知道怎么做的话!)如何满足这个要求?
  • @AndyRoss -- 如果我给它一个外部 RAM 模块并配置它的堆,我的系统会很乐意暴露可能由不正确的内存管理导致的错误。但我没有给它,也没有这样做的计划。我不知道如何复制动态内存管理器,因为这是我第一次尝试。我怀疑,如果一个人从不做任何他不知道该怎么做的事情,他将一事无成。
  • 所以这个问题更像是“malloc 是如何实现的?”
  • 我们在谈论什么系统?几乎所有微控制器工具链都带有一个实现简单 malloc() 的 C 库。

标签: c memory-management static malloc


【解决方案1】:

关于可以编写的最简单的分配器:

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

就是这样。显然,如果你经常打电话给free,这个策略很快就会耗尽内存。所以你可以引入一个并发症:

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

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

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

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

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

【讨论】:

  • 这就是我的想法,感谢您确认我并没有完全偏离基础。
  • @ken:我认为总结是编写内存分配器非常简单。写一个好的不是,但你可能不需要一个好的。一旦你写了一篇糟糕的文章并观看了它的实际操作,你就能更好地了解优秀的人正在努力做什么。
  • K&R 有一个基本的分配器作为例子。
【解决方案2】:

一个老家伙,但一个好人(用于描述问题的博客文章):http://g.oswego.edu/dl/html/malloc.html

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

【讨论】:

    【解决方案3】:

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

    我认为关键概念是分配的块也始终包含到下一个空闲块的偏移量,这就是您使用自己的数组仅跟踪其中分配的内容的方式。

    【讨论】:

      猜你喜欢
      • 2022-11-10
      • 1970-01-01
      • 2020-04-08
      • 2013-07-04
      • 2020-11-23
      • 2012-12-26
      • 2016-02-13
      • 2013-11-20
      • 2013-02-23
      相关资源
      最近更新 更多