C++ – Is heap fragmentation a problem in bare-metal arm with g++

cembedded-systems

I am converting a project from C to mixed C/C++. It is going quite nice, and the new features are really lightening the work.

The platform is an ARM SAM4, compiler is arm-none-eabi-g++. This is not a safety-related equipment, but still could be left running for months and is not supposed to restart sporadically.

The original C project has managed quite nicely to solve problems without a single malloc call, allocating statically all needed data. For example, arrays with unknown size are allocated to the maximum expected size.

Now I am considering can I get away with using new. For example, all STL containers hold their content in the heap. Just adding a new element to a vector can cause de-allocation of a whole region of the heap and allocation of another one.

Will there be fragmentation issues?

Related:

What is memory fragmentation?

Best Answer

There is no way of telling if heap fragmentation will be a problem in your application. We can't tell, because heap fragmentation is the result of certain usage patterns of the memory (de-)allocator and you have not provided any info on that pattern.

In general, you can expect fragmentation issues if you constantly allocate and deallocate objects with varying sizes and varying lifetimes, such that it would be rare to be able to fit a new memory request into a slot that was recently released or that many memory allocations would leave an unusable small number of bytes unused between them. Such patterns can be very subtle and they also depend on the allocation strategy used by new/delete. Also note that leaked objects effectively get eternal lifetime as far as the memory management is concerned.

You can try to avoid fragmentation by setting up multiple allocators, so that you can allocate different types of objects from different pools. If all objects in a pool have close to the same size, then fragmentation won't be an issue.

Another option is to try to organize your allocations such that objects with a similar lifetime are allocated close together (in time). That also limits the chances of getting fragmentation, because the objects that are always there will be close together in one part of the heap and the more volatile objects will get allocated from a different part of the heap.


Growing a std::vector<> doesn't cause memory fragmentation, but it does have the nasty side effect that you effectively need double the normal amount of memory while growing the vector. This can be an issue if you only have a limited amount of RAM available.
To avoid this problem, you can use std::vector<>::reserve() to set the allocated memory close to the expected maximum.

Related Topic