Stack, Heap & Static Allocation
Why firmware avoids malloc, how fixed-size memory pools work, and how to keep the stack from overflowing.
malloc and free work on microcontrollers, but most safety and automotive coding standards forbid them after initialisation. Allocation time is not bounded, the heap fragments over months of uptime, and an allocation that fails in the field is hard to recover from.
The stack
void handler(void) { uint8_t frame[4096];... } static uint8_t frame[4096]; (or a pool block)
A 4 KB local array on a 2 KB stack overflows immediately and corrupts unrelated variables.
msg = malloc(sizeof *msg); // in the main loop, forever Allocate from a fixed-block pool, or preallocate at init
Repeated malloc/free of varying sizes fragments the heap until an allocation fails months later.
Why is a fixed-block pool immune to fragmentation?
All blocks have the same size, so any free block satisfies any request; free space can never be split into unusable pieces.
How can you measure the real stack usage of firmware?
Fill the stack area with a known pattern at start-up (stack painting), exercise the worst case, then find the deepest overwritten address; also check -fstack-usage reports.