2.10.2. malloc 支持

malloc()realloc()calloc()free() 均建立在堆抽象数据类型的基础上。 可以在 Heap1 和 Heap2 之间进行选择,它们均提供了堆实现。

malloc()realloc()calloc() 的缺省实现维护一个 8 字节对齐的堆。

Heap1:标准堆实现

Heap1(缺省实现)实现最小且最简单的堆管理器。 堆是作为单链接可用块列表(按地址升序排列)进行管理的。 分配策略是地址优先匹配。

此实现具有较低的开销,但 malloc()free() 的开销随可用块数量的增加呈线性增长。 可分配的最小块是 4 个字节,并且产生 4 个字节的附加开销。 如果希望得到 100 个以上的未分配块,则建议使用 Heap2。

Heap2:可选堆实现

Heap2 提供了较为紧凑的实现方式,malloc()free() 的开销随可用块数量的增加呈对数增长。 分配策略是地址优先匹配。 可分配的最小块是 12 个字节,并产生 4 个字节的附加开销。

如果在存在数百个可用块的情况下需要大致恒定的性能(不会随时间的推移而发生变化),建议使用 Heap2。 要选择可选的标准实现,请使用以下任一方法:

  • 汇编语言中的 IMPORT __use_realtime_heap

  • C 中的 #pragma import(__use_realtime_heap)

使用 Heap2

Heap2 实时堆实现必须知道堆占用的最大地址空间。 地址范围越小,算法越有效。

缺省情况下,将堆的范围设置为 16 MB,从堆的起点(定义为 __rt_initial_stackheap()__rt_heap_extend() 为堆管理器分配的第一个内存块的起点)开始。

堆范围是由以下代码设置的:

struct __heap_extent

{

    unsigned base, range;

};	

	

__value_in_regs struct __heap_extent __user_heap_extent(	

             unsigned defaultbase, unsigned defaultsize);

__user_heap_extent() 的函数原型位于 rt_misc.h 中。

Heap1 算法不需要在堆范围内设置边界,因此,它根本不会调用此函数。

如果以下条件成立,则必须重新定义 __user_heap_extent()

  • 需要的堆占用的地址空间超过 16 MB

  • 内存模型可提供一个内存块,其地址低于提供的第一个内存块的地址。

如果事先知道堆的地址空间范围很小,则不需要重新定义 __user_heap_extent(),但这样做会加快堆算法的速度。

如果未定义此例程,则输入参数是所使用的缺省值。 例如,可以将缺省基址值保持不变,而只调整大小。

Note

返回的大小字段必须是 2 的幂。 库不检查这一情况;如果不满足此要求,则会以意外方式失败。 如果返回的大小为 0,则将堆范围设置为 4 GB。

从裸机 C 中使用堆实现

要在未定义 main() 函数并且未初始化 C 库的应用程序中使用堆实现,请执行以下操作:

  1. 调用 _init_alloc(base, , top) 以定义要作为堆管理的内存的基址和顶部地址。

  2. 定义 unsigned __rt_heap_extend(unsigned size, void **block) 函数以处理用于在堆满时扩展堆的调用。

alloca()

alloca() 的行为与 malloc() 相同,只不过 alloca() 具有自动垃圾回收功能(请参阅alloca())。

Copyright © 2007 ARM Limited. All rights reserved. ARM DUI 0349AC
Non-Confidential