1

I finally understand why people do not allocate memory when it comes to micro-controllers. The reason is because as you allocate different objects on the heap of various sizes and then you delete them you end up with holes. This is called heap fragmentation. Anyways I know what is heap fragmentation. I just want to know how it works. So that I know when I can use the new keyword to allocate memory and when not..

(1) To make things simple consider this example. Lets say my heap looks like this. The bottom numbers represent the addresses. In a real example I will be allocating structs with larger sizes but lets use bytes to make things simple.

0    0    0    0    0    0    0    0    0    0    
1    2    3    4    5    6    7    8    9    10

(2) I allocate a char with value 123 in memory. Now my heap looks like this

1    0   123   0    0    0    0    0    0    0    
1    2    3    4    5    6    7    8    9    10

the first 2 bytes 1 0 store the size of the data being allocated followed by the byte 123 that has the actual value.

(3) I allocate another char with value 111 in memory. Now my heap looks like this

1    0   123   1    0   111   0    0    0    0    
1    2    3    4    5    6    7    8    9    10

(4) I delete the first object created on step 2 with value 123. It now looks like:

0    0    0    1    0   111   0    0    0    0    
1    2    3    4    5    6    7    8    9    10

I now have a hole at the beginning (heap fragmentation)

Now my question is if I where to allocate another byte say 222 will it be allocated on the beginning like this?

1    0   222   1    0   111   0    0    0    0    
1    2    3    4    5    6    7    8    9    10

Or will it be allocated at the end like this?

0    0    0    1    0   111   1    0   222   0    
1    2    3    4    5    6    7    8    9    10

If arduino is smart enough to place that object at the beginning, then I will no be that afraid of using the new keyword as long as I am allocating objects of small sizes and never allocating to many of them.

Reason why I am asking this question is because I have a class Queue that I use in c++. Whenever I add an item to that queue it allocates the objects that I create. The objects that I pass to that queue are 10 bytes. The queue size is never larger that size 30. Will it be safe if that queue is constantly allocating (enqueing) and deleting (dequeing) items?


Edit

Sorry for the question I guess I asked this question when I should had done more research. Thanks to your comments and my previous question I now know that this only occurs when allocating memory of different sizes.

Tono Nam
  • 938
  • 7
  • 19
  • 2
    Heap fragmentation occurs specifically when you are allocating objects of different sizes and a smaller object is placed into a larger hole leaving a bit of left over memory too small for another object later on. With single bytes or always the same size objects you won't get that problem, since a hole will always be the right size. – Majenko Jul 23 '20 at 21:28
  • 1
    When having always the same object size (in your example always only 3 bytes per object) you don't have that problem. I added a small paragraph about that in my answer to your previous question, because it fits good into the answer. – chrisl Jul 23 '20 at 21:35
  • @chrisl thanks I just want to make sure I understand because I am allocating a lot of memory in my code. For example all the events that ocur on arduino of interest I place them on a queue. Then my library uses that queue to send the messages with the NRFL24L01 radio. Thanks for all the help! – Tono Nam Jul 23 '20 at 21:48
  • I suggest you keep at that idea. When you hit the wall and can’t understand why it sometimes just does weird things you can’t explain then come back and we can help you find a proper memory budget. Doing what you’re doing on a microcontroller is like trying to live like a king on minimum wage. You can use credit and pull it off for a while but eventually it catches up with you. Unless you’re writing code to make sure each of these queued things fits neatly into memory eventually you’ll queue something that doesn’t fit. And there will be no explanation for what happens next. – Delta_G Jul 23 '20 at 22:01
  • 3
    Your method is good thinking on a PC. But on a microcontroller you’re asking for trouble. It would be best to go ahead and set a limit for how many things can be queued and how big they can be. And if you can set that limit then you no longer need dynamic allocation. You don’t have anything to share memory with so why not just allocate what you need from the start. You’ll see. – Delta_G Jul 23 '20 at 22:03
  • 1
    You may want to take a look at [the source code of `malloc()`](http://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/libc/stdlib/malloc.c?revision=2149&view=markup) (this is the AVR version): it is very well documented in the comments. And maybe also at [this answer](https://arduino.stackexchange.com/a/8947) to a related question. – Edgar Bonet Jul 23 '20 at 22:24

0 Answers0