Home > On-Demand Archives > Q&A Sessions >

Live Q&A - Dynamic Memory Allocation & Fragmentation in C/C++

Colin Walls - Watch Now - EOC 2023 - Duration: 19:52

Live Q&A - Dynamic Memory Allocation & Fragmentation in C/C++
Colin Walls
Live Q&A with Colin Walls for the talk titled Dynamic Memory Allocation & Fragmentation in C/C++
italicssurround text with
boldsurround text with
**two asterisks**
or just a bare URL
surround text with
strikethroughsurround text with
~~two tilde characters~~
prefix with

Score: 0 | 1 year ago | 2 replies

Thanks for the great talk, Colin! I have a few thoughts/questions for you about it:

  1. It seems like using a block memory scheme is the best option for dynamic memory if deterministic time and/or fragmentation are concerns; also ideally the implementation is reentrant if in a multi-threaded environment. Is that right? Are you able to recommend any implementations that meet those criteria? Any that meet safety requirements like for MISRA?
  2. Is it really true that "fragmentation isn't possible" using a block memory scheme? I would argue it is, if only because I might find myself in the same scenario where my memory utilization is <100% but I can't find a large enough contiguous space to hold whatever piece of data I'm trying to fit into the heap.
  3. Do you know of any dynamic memory implementations that return something like "void **" to allow for defragmentation?
  4. "Double-freeing" a pointer is also a concern with dynamic memory, right?
  5. Allowing dynamic memory allocations only at system start-up seems like another solution that solves every problem except memory exhaustion. Is that also a possible solution?
Score: 0 | 1 year ago | 2 replies

1) Most RTOSes - if not all - meet these primary criteria. There is no reason why they should not be MISRA compliant. If you have source code, you can verify. A number of RTOSes claim to be compliant anyway.
2) Fragmentation is not possible because there is either an available block or there are no blocks available.
3) I do not know if any, though it would make some sense. However, de-frag would introduce non-detreminism.
4) Why?
5) Doing allocation at start up results in essentially static allocation, which is a very good idea!

Score: 0 | 1 year ago | 1 reply

Regarding 4: I was just curious. You list the problems/concerns with dynamic memory around 14:51 so I was wondering if "double-freeing a pointer" could maybe also be on that list, since that seems to be a problem unique to dynamic memory.

Regarding 2: Maybe you could help me by defining "fragmentation" and how a block memory scheme prevents it?

Score: 0 | 1 year ago | 1 reply

If you called free() to deallocate some memory and then called it again, I believe the second call would do nothing.
Fragmentation is when the allocated memory is scattered around the heap, with unused gaps which are no large enough for allocation demands.

Score: 0 | 1 year ago | no reply

Well, fwiw, OWASP (and others) seems to indicate that the result of a double free is undefined, possibly resulting in a security vulnerability. It seems an easy enough thing to check in other implementations of free(), but maybe not something that can be assumed.

Score: 0 | 1 year ago | 1 reply
  1. Agree that with pools there can't be fragmentation, but if pools with right or larger block size are full, then you may find yourself in a situation where there would be enough free memory to fulfill the request, but it is allocated for smaller blocks and therefore the request fails. It is not fragmentation, but the effect for the end user is the same.
    (And this just remarks the importance of tuning the size of each pool)
Score: 0 | 1 year ago | 1 reply

Yeah, this is exactly what I was thinking. But I had thought that "fragmentation" is described as the problem that results from an inability to allocate memory despite the heap having sufficient overall space, due to the fact that that space is spread out. It would seem to me that a block memory scheme is still susceptible to that problem (even if it's intentional) and therefore doesn't solve the problem of "fragmentation". If I partition my heap into 1024 blocks of 16 bytes and then make 1024 requests for 1 byte each then I've exhausted my heap despite only using 6% of the available memory; shouldn't that qualify as "fragmentation"? Perhaps a block memory scheme helps limit the amount of fragmentation that could occur, but I'm struggling to see how it eliminates it.

Score: 0 | 1 year ago | no reply

The final effect is indeed the same - despite counting a grand total of enough free memory, the system can't fulfill the allocation request for how the free memory is organized.
Fragmentation refers to a condition in which free memory is fragmented and interspersed with in-use memory. This condition is not possible when using pools as described by Colin.
Though there is no magic wand to solve dynamic allocation :-) . Pools need to be carefully designed (and tuned) both to limit the case you describe (slack space at the end of a block) and the case I described (wrong dimension of pools with respect to the use).

Score: 0 | 1 year ago | no reply
  1. In Windows 3.0 / 3.1 (and possibly earlier versions) the allocation function (GlobalAlloc/LocalAlloc) returns a handle. In order to access the allocated memory you need to Lock the handle and Unlock it when done. This allows the system to move memory around when it is not locked by any process. BTW if you needed memory to stay fixed a dedicated flag was available in the allocation function.
Score: 0 | 1 year ago | 1 reply

Is there a library, tool or example technique that will help developers visualize the heap fragmentation in a dynamic execution environment? For example, is there a heap profiler that can run alongside the application that will show the state over the heap every 10 ms or every period that's configurable?

Score: 0 | 1 year ago | no reply

I am not familiar with such a tool. I guess it would need to be run as a separate task or timer tick interrupt service routine.

Score: 0 | 1 year ago | no reply

Oh, also I had read on Embedded Artistry about stack protections offered by GCC and Clang and thought I'd post a link for others.

11:36:10	 From  Levy Gabriel : What's the impact of fragmentation in sensor data stored via DMA? What are the strategies to overcome this issue in C/C++?
11:36:25	 From  Nathan O. : If you don't know the size of the data you have to process and use dynamic allocation, are you not just pushing the problem away and hoping for the best that it won't reach over the capabilities of the system ?
11:37:04	 From  Naishadh K : Great talk, Collin. Suppose, we are careful of freeing the memory after malloc. Are there any other ways memory leak can happen? If yes, what are the things that needs to be taken care of?
11:37:31	 From  Levy Gabriel : Let me rephrase: fragmentated memory
11:37:39	 From  Levy Gabriel : The DMA data is continuous
11:37:58	 From  Jim Norton : I didn't watch the talk. But I do wonder if there has been any work/research towards creating a system that can defrag memory in a low priority task that can still keep near hard real-time requirements?
11:38:40	 From  BobF : Re: Choice between Static/Dynamic. Presumably, the life-time of the product also potentially plays a part .... how well it's originally designed and whether subsequent field support i.e. OTA is serious!
11:39:33	 From  doolittl : When dynamic memory is used, do you have a favorite tool or similar strategy for debugging fragmentation (or leak) issues?
11:42:07	 From  Gonzalo : Which cases really need to use dynamic allocation? In power electronics and implementation of current control systems I have always avoided dynamic allocation because the real time capacity is absolutely needed, otherwise something will blow up. Anyway, now I wonder how to use dynamic allocation securely if needed to avoid depriving me forever not to use it in other applications.
11:42:50	 From  Nathan O. : Any recommendation on how to define the heap size ? Should we assume max load / size for everything ?
11:43:13	 From  John : Can you elaborate a bit more on how overflowing, and especially *underflowing* the stack would happen? Because isn't the compiler at fault for these (not the programmer)? Which doesn't actually solve the problem of course but does impact how these issues can be fixed. Thanks!
11:45:20	 From  John : If you are on bare metal, and don't have an RTOS, any recommendations? Should static alloc be preferred more strongly?
11:45:20	 From  Nathan O. : Répondre à "Any recommendation..."

Then you have to carefully define the size of your stacks ;)
11:45:52	 From  Jim Norton : Suppose we could create an allocator that returned a handle to allocated memory instead of a direct pointer. Would that get us closer to being able to have a defragment system in languages that use pointers?
11:47:20	 From  Jim Norton : Overflow is easy to create with recursion
11:47:52	 From  John : Cool, thanks!
11:49:18	 From  John : Basically, write your own garbage collection, right?
11:49:32	 From  Jim Norton : :-)
11:50:03	 From  Keith J : Thank you Colin
11:50:14	 From  Jim Norton : Thanks guys! Appreciate it
11:50:39	 From  Charles Miller : Thank you, gentlemen.
11:50:52	 From  Naishadh K : Reacted to "Thank you Colin" with 👍