5.4.7.1 Dynamic Memory Allocation for PIC Devices

The MPLAB XC8 C Compiler implements a simplified dynamic memory allocation scheme for projects targeting PIC18 or Enhanced Mid-range devices and when the C99 language standard has been selected. Dynamic memory allocation is not implemented for other devices, due to their restrictive memory arrangement. Dynamic allocation is not available for any device when the C90 language standard has been selected.

The simplified dynamic memory allocation scheme permits the use of all the standard memory allocation library functions, but the algorithms employed are cut down to reduce the resources used. This is advantageous for devices with small amounts of data and program memory, but requires that this form of allocation be used carefully to avoid memory wastage.

Initially, memory can be allocated as required, subject only to the maximum size reserved for the heap. Memory blocks that are freed after allocation are maintained in a linked list and will be considered for re-allocation whenever additional memory is subsequently requested. The management of these freed blocks, in particular how they might be merged, is rudimentary.

How your program is structured can affect how efficiently dynamic memory allocation operates. If a block of allocated memory can be freed before allocating additional blocks, this will aid in the reuse of the freed memory blocks. Allocating and freeing memory blocks in any order will lead to fragmentation of the unused memory in the heap, which might render it unavailable for future allocation. Prudent program designers will avoid using dynamic memory allocation, if at all possible.

Attempting to allocate 0 bytes of memory will result in 1 byte being requested, with a pointer to that memory, when available, being returned in the usual way.

Reallocation of memory using realloc() will always allocate a new block with the requested size, where possible, and then free the old block after the existing data has been copied to the new block.

As the heap can grow during program execution, there is the potential for it to overwrite other memory areas or exceed the memory of the device. To prevent these situations, the heap can be limited to a maximum size, which is specified using the -mheap option (see 4.6.1.11 Heap Option). If an attempt at runtime to allocate memory would result in the heap exceeding the maximum size, the allocation will not take place and the allocation function will return a null pointer to indicate this situation.

Programs that use a heap might also use software stacks for memory allocation of stack-based objects. (One software stack is used by each call graph in a program, e.g. main-line code and interrupt functions.) As both the heap and stacks grow and shrink during program execution, device memory not consumed by statically allocated objects must be shared between them. The maximum size of the software stacks can also be set. That is performed using the -mstack option (see 4.6.1.23 Stack Option). An argument of auto can be specified to both the -mstack and -mheap options, in which case the compiler will evenly distribution free memory between the stack and heap.

The memory allocated to the heap is held by a psect called heap.

The maximum amount of heap memory used by a program is not known at compile time, but the maximum amount of memory reserved for the heap is shown in the memory summaries and reports produced by the compiler after compilation.