C and C++ programmers very often allocate and de-allocate memory on the heap without the proper understanding on how these low-level facilities work and what happens underneath. But these memory related problems becomes a great concern in the systems with shortage of almost all the resources including memory, like embedded real-time systems. This dynamic behavior tends to be non-deterministic and the failure is hard to contain. Similarly memory allocation failure on such systems can be fatal. Unlike a desktop application, most embedded systems do not have the opportunity to pop up a dialog and discuss options with the user. Often, resetting is the only option, which is unattractive. This technical paper attempts to discuss the strategies to achieve clean code and appropriate memory management.
Memory management is the process of recognizing when allocated objects are no longer needed, de-allocating (freeing) the memory used by such objects, and making it available for subsequent allocations. In C and C++ programming languages, memory management is programmer’s responsibility. The complexity of this task leads to many common errors that can cause unexpected or erroneous program behavior and crashes. As a result, a large proportion of developer time is often spent debugging and trying to correct such errors.
The newer languages (Java, Python, and Perl) have automated memory management. This ranges from Python’s simple reference-counted model to Java’s sophisticated garbage collector. A garbage collector automatically analyzes the program’s data and decides whether memory is in use and when to return it to the system. When it identifies memory that is no longer in use, it frees that memory. This automatic memory management enables increased abstraction of interfaces and more reliable code. To the programmer, however, the final result is nearly always the same: no more worrying about memory errors.
In order to ease up C/C++ programmer’s life, many memory errors detection tools are available in the market such as Valgrind, Electric Fence, and Purify. These tools can be used to detect some memory defects, but these cannot guarantee their absence. For the ones who do not have such a tool or don’t want to use, there are two strategies available to the programmer. The first strategy must always be to architect memory errors out of your system. The second is the old-school way: code inspection. To restrict the search in order to speed up the debugging process, one should first review the pieces of code with a dense use of pointers and casts.
Continue reading: Best Practices – Memory Management in C and C++ (pdf)