Non-Confidential | PDF version | ARM 100073_0608_00_en | ||

| ||||

Home > The ARM C and C++ Libraries > Stack and heap memory allocation and the ARM C and C++ libraries > Choosing a heap implementation for memory allocation functions |

`malloc()`

, `realloc()`

, `calloc()`

, and `free()`

are built on a heap abstract data type. You can choose between Heap1 or Heap2, the two provided heap implementations.

The available heap implementations are:

- Heap1, the default implementation, implements the smallest and simplest heap manager.
- Heap2 provides an implementation with the performance cost of
`malloc()`

or`free()`

growing logarithmically with the number of free blocks.

`malloc()`

, `realloc()`

, and
`calloc()`

maintain an eight-byte aligned heap.Heap1, the default implementation, implements the smallest and simplest heap manager.

The heap is managed as a single-linked list of free blocks held in increasing address order. The allocation policy is first-fit by address.

This implementation has low overheads, but the performance
cost of `malloc()`

or `free()`

grows linearly
with the number of free blocks. The smallest block that can be allocated
is four bytes and there is an additional overhead of four bytes.
If you expect more than 100 unallocated blocks it is recommended
that you use Heap2.

Heap2 provides an implementation with the performance cost of `malloc()`

or `free()`

growing
logarithmically with the number of free blocks.

The allocation policy is first-fit by address. The smallest block that can be allocated is 12 bytes and there is an additional overhead of 4 bytes.

Heap2 is recommended when you require near constant-time performance in the presence of hundreds of free blocks. To select the alternative standard implementation, use either of the following:

`IMPORT __use_realtime_heap`

from assembly language.`__asm(".global __use_realtime_heap\n\t")`

from C.

The Heap2 real-time heap implementation must know the maximum address space that the heap can span. The smaller the address range, the more efficient the algorithm is.

The heap must fit within 16MB of address space.

By default, the heap extent is taken to be 16MB starting at the beginning
of the heap (defined as the start of the first chunk of memory given to the heap manager
by `__rt_initial_stackheap()`

or `__rt_heap_extend()`

).

For AArch32 targets, the heap bounds are given by:

struct __heap_extent { unsigned base; size_t range; }; __attribute__((value_in_regs)) struct __heap_extent __user_heap_extent( unsigned ignore1, size_t ignore2);

For AArch64 targets, the heap bounds are given by:

struct __heap_extent { unsigned long base; size_t range; }; __attribute__((value_in_regs)) struct __heap_extent __user_heap_extent( unsigned long ignore1, size_t ignore2);

The function prototype for `__user_heap_extent()`

is in rt_misc.h.

(The Heap1 algorithm does not require the bounds on the heap extent. Therefore, it never calls this function.)

You must implement `__user_heap_extent()`

if:

- You require a heap to span more than 16MB of address space.
- Your memory model can supply a block of memory at a lower address than the first one supplied.

If you know in advance that the address space bounds of your heap are
small, you do not have to implement `__user_heap_extent()`

,
but it does speed up the heap algorithms if you do.

The input parameters are the default values that are used if this routine is not defined. You can, for example, leave the default base value unchanged and only adjust the size.