Because most real allocation patterns are not arbitrary-size-and-lifetime, they're uniform-size or batch-scoped, which the specialized allocators handle better. A fixed number of tasks, peripherals, and buffers → static arrays. Many same-size objects (packets, nodes, control blocks) cycling through alloc/free → a pool, O(1) and fragmentation-free. Bursts of temporary parsing/processing state → an arena reset per batch. Once you map each need onto the right strategy, the residue that genuinely requires arbitrary-size, long-lived, unpredictable allocation, the only thing general malloc is actually needed for, turns out to be small or nonexistent. And avoiding the heap buys determinism (bounded WCET), no fragmentation, link-time-known memory, and no unrecoverable exhaustion, exactly the properties real-time and safety-critical systems require, and why standards like MISRA restrict dynamic allocation. So it's less that the heap is forbidden and more that, pattern by pattern, a better-fitting allocator almost always exists.
Data Structures & Algorithms · Interview question
Why does well-designed embedded firmware rarely need the general heap?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
Static vs Dynamic Allocation
How to give data structures memory on a constrained device: static arrays, fixed-block pools, and arena allocators, the O(1), fragmentation-free alternatives to general malloc.