Any bright-eyed, naive developer exploring the boundaries of their knowledge might have a vision of a utopia of perfect portability. A world where your application code is 100% hardware agnostic; a world where whether programming a server, a desktop or mobile app, or an embedded device, the models, data structures, algorithms, and practices are exactly the same. When considering dynamic memory allocation on embedded systems, one might think, “Surely we should be able to write portable code that can utilize nearly all of the standard C/C++ library routines and practices. Maybe we have to forgo filesystems, but these people advising everyone to avoid heap allocations on embedded systems are just old, jaded embedded developers who aren’t up with the times.” (not that I have ever had these thoughts 😉)
They’ve got heaps, we’ve got heaps, together we use heaps.
If we have a heap on our embedded system (which we generally can), why not use it?
The core issue, as I see it, is the user interface. When a desktop system (or mobile device) runs out of memory, it can notify the user who can then, typically, take some action to free up some memory. Alternatively, in the case of mobile devices (at least Android), the device can dynamically kill old processes that are still loaded in the background. The user of an embedded system, on the other hand, just knows that their device isn’t working properly. Whether it keeps resetting or starts blinking some red light, not only do they not know what the problem is, but they also have no options to solve the problem.
This quickly becomes an issue of determinism. I come from a background of bare-metal systems in safety-critical applications. In my mind, any device which the user cannot take steps to “optimize” must be deterministic (or at least perceived as). By this, I mean that the device should know exactly how much memory it will ever need and how long it will take to complete any possible task. For example, any design in which the fragmentation rate of the heap doesn’t quickly reach 0 (actually 0, not asymptotic) is unacceptable. In practice, deterministic memory use is the rule anyway. Desktop and mobile applications have to deal with many dynamic conditions such as the hardware they are running on, the other applications or system processes running concurrently, complex user inputs, etc. These conditions do not exist in the embedded space.
The use-case still remains that an object my a lifetime unconstrained by the scope in which it was instantiated. The easy way to solve this is to make those objects global, but that is certainly not best practice.
Just call me jaded…
Written with StackEdit.