3

我在某些项目中看到(基本上是许多 C/C++ 中的嵌入式应用程序),它们管理动态分配如下

  • 在初始化期间获取大量内存(根据需要)。该区域被指定为该应用程序的堆。
  • 跨不同例程的所有动态分配都是通过为分配和维护(跟踪和调试分配)而设计的包装器在此内存中进行的。

问题:

Q1:上面提到的私有堆管理设计的优点。

Q2:C、Linux API 中是否有任何内置函数提供接口以在先前分配的块中进行动态分配。我找遍了它,但无法抓住它

Q3:如果 Q2 中提到的选项不可用。关于如何实现 Q2 中提到的目标的任何想法。

4

2 回答 2

2

正如您所说,基本上许多 C/C++ 中的嵌入式应用程序使用不同的方法来获取您定义的动态内存。

我认为它基本上是为了减少内存和正确使用而完成的。

如果您尝试了解 malloc() 或 calloc() 函数如何在 c 中用于动态内存分配,那么您肯定会得到答案。我可以解释一下... 它(malloc)真正做的是维护一个空闲内存的链表。但最初,空闲列表是空的。当第一个 malloc() 被调用时,我们调用 sbrk() 来为空闲列表获取一块新的内存。这块内存被分割,一部分归还给用户,剩下的回到空闲链表。会有一个全局变量 malloc_head,它是空闲链表的头部。当 malloc() 被调用时,它会在它的列表中寻找一块足够大的内存。如果它找到一个,那么它将从链表中删除该内存并将其返回给用户。当调用 free() 时,内存被放回链表中。现在,为了提高效率,如果空闲列表上有一块比请求大得多的内存,然后它将该块分成两块——一个是请求的大小(填充为 8 的倍数),其余的。其余的放在空闲列表上,请求大小的一个返回给用户。

有关详细信息,请尝试参考http://web.eecs.utk.edu/~huangj/cs360/360/notes/Malloc2/lecture.html http://web.eecs.utk.edu/~huangj/cs360/360 /notes/Malloc1/lecture.html

问题1->现在对于您的第一个问题,优势可能是以更有效的方式节省内存和分配,这取决于正在实施其方式的项目。

问题2->我还没有在 c 中看到任何内置库或 API 这样做。

问题3->要实现您自己的 API,您需要参考给定的 C 链接和 R&K 书。这本书解释得更详细。

于 2012-11-29T12:26:28.607 回答
2

Q1:

  1. 性能- 在堆被分配之后(通常在初始化期间完成),所有未来的分配都非常快,它主要只是堆内的一些指针运算。
  2. 碎片- 大内存块的单一分配可防止由于多个分配/释放造成的内存碎片。
  3. 控制- 拥有所有可用内存使系统更加健壮。这在分配失败是不可接受的情况下可能很重要。

预分配内存与后备列表的概念密切相关。

Q2:

我不知道 C 中有这样的 API,但在 C++ 中实际上有内置的运算符可以帮助实现 - 请参阅Placement new。这样的实用程序也应该很容易在 C 中实现。

问题 3:

例如(非常高级):

  1. 分配内存。
  2. 在内存中创建一个空闲空间块的堆结构(最初它将包含一个代表整个内存的块)。
  3. 创建占用的内存块的堆结构(最初它将是空的)。
  4. 分配时 - 遍历堆并找到适当大小的块;从堆中删除它并填充新数据。计算块中的剩余内存并将其重新插入堆中。被占用的块插入到被占用的块堆中。
  5. 释放时 - 从占用的块堆中删除块并将其插入空闲内存堆。
于 2012-11-29T12:43:11.647 回答