Deterministic dynamic memory allocation & fragmentation in C & C++
Dynamic Memory in C++Management of dynamic memory in C++ is quite similar to C in most respects. Although the library functions are likely to be available, C++ has two additional operators " new and delete " which enable code to be written more clearly, succinctly and flexibly, with less likelihood of errors. The new operator can be used in three ways:
p_var = new typename;
p_var = new type(initializer);
p_array = new type [size];
In the first two cases, space for a single object is allocated; the second one includes initialization. The third case is the mechanism for allocating space for an array of objects. The delete operator can be invoked in two ways:
delete p_var;
delete[] p_array;
The first is for a single object; the second de-allocates the space used by an array. It is very important to use the correct de-allocator in each case. There is no operator that provides the functionality of the C realloc() function.
Here is the code to dynamically allocate an array and initialize the fourth element:
int* pointer;
pointer = new int[10];
pointer[3] = 99;
Using the array access notation is natural. De-allocation is performed thus:
delete[] pointer;
pointer = NULL;
Again, assigning NULL to the pointer after de-allocation is just good programming practice.
Another option for managing dynamic memory in C++ is the use the Standard Template Library. This may be inadvisable for real time embedded systems.
Issues and Problems
As a general rule, dynamic behavior is troublesome in real time embedded systems. The two key areas of concern are determination of the action to be taken on resource exhaustion and non-deterministic execution performance. When considering dynamic memory utilization, the likely problem area is the use of malloc().
Use of malloc().There are a number of problems with dynamic memory allocation in a real time system.
Firstly, the standard library functions (malloc() and free()) are not normally reentrant, which would be problematic in a multithreaded application. If the source code is available, this should be straightforward to rectify by locking resources using RTOS facilities (like a semaphore).
A more intractable problem is associated with the performance of malloc(). Its behavior is unpredictable, as the time it takes to allocate memory is extremely variable. Such non-deterministic behavior is intolerable in real time systems.
Without great care, it is easy to introduce memory leaks into application code implemented using malloc() and free(). This is caused by memory being allocated and never being de-allocated. Such errors tend to cause a gradual performance degradation and eventual failure. This type of bug can be very hard to locate.
Memory allocation failure is a concern. 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.
If allocation failures are encountered during testing, care must be taken with diagnosing their cause. It may be that there is simply insufficient memory available " this suggests various courses of action. However, it may be that there is sufficient memory, but not available in one contiguous chunk that can satisfy the allocation request. This situation is called memory fragmentation.


Loading comments... Write a comment