If you have some background in computer programming languages, and you just started working with low-memory MCUs, you may be tempted to do some dynamic allocation in your programs. After all, that’s what smart memory management is all about, right? Well, the truth is that in the vast majority of cases, dynamic allocation in MCUs will be pointless and even detrimental. In this post, I will explain why.
The Computer Way
Let’s consider the three reasons – two of them conflicting, actually – why anyone would want to perform dynamic memory allocation, for instance using malloc or new, in the first place.
1. We want as much memory as possible: If we don’t know in advance how much memory there is on the system(s) where our code will run, we use dynamic allocation to milk the operating system at runtime for all its worth. Without dynamic allocation, we’ll have to limit ourselves to the worst-case scenario of minimum memory.
2. We want as little memory as possible: When our program has to work under an OS that manages other software as well, we usually don’t really want to hog all the memory resources, because our users will be quite upset.
3. Same limited memory required for entirely different and separate operations: In rare cases, our program will perform mutually exclusive operations, e.g. code compilation and debugging, or audio pre-processing and playback. Then we may re-use the same memory space, and utilize dynamic allocation of it for the convenience and safety of not having to deal with raw memory bytes.
There may be other, lesser reasons to want to allocate and free memory areas, but I think the above are really the major ones.
The MCU Way
Consider, now, the humble and ubiquitous Arduino Uno, with its exactly 2KB of RAM. We know it will always be 2KB, not a single bit more, so reason #1 is no longer relevant. We also know that there’s no OS on the Arduino, no other programs to share memory with; attempting to be memory-efficient in this particular sense is like having a whole king-size bed for yourself and sleeping intentionally on its corner. There goes reason #2!
What about the third reason? I’ll cut that one just a little bit of slack, because in programming you should never say never; nonetheless, in my experience it’s really rare to have such requirements from an MCU-based system.
So far, we saw no reason to prefer dynamic allocation over static. What about the other way around? Well, naturally there’s some overhead to dynamic allocation, which will cost you a little program space and performance. Also, since there’s no OS to manage the memory and handle exceptions gracefully (more or less), your program is susceptible to all sorts of allocation issues which will be a nightmare do debug.
In Summary
When programming on a modern computer, there are great reasons to allocate memory dynamically – one would even be a fool to ignore them. However, these reasons are simply irrelevant when small MCUs are concerned. Therefore, when you program on an Arduino, a PIC or a similar platforms, think carefully: are you allocating memory dynamically just because that’s how you’d do it on a computer? Or do you really understand the costs and consequences, and have a proper justification for your decision?