Dynamic Array?

anonymous wrote on Wednesday, December 15, 2010:


Is it a could idea to use the vPortMalloc/free function from the heap2 implementation, to create dynamic sized arrays runtime?
I guess its not more dynamic, then the the allocated total heap size if the FreeRTOS config file?

I have some data in the storage (flash), that at some point must be read and presented on the display. The data is various text strings and has different length and layout, so I could make sure that all my variables and arrays are big enough for worst case. But again, thats a big waste of space.


edwards3 wrote on Wednesday, December 15, 2010:

Heap_2 is fast so no worries there, but will suffer fragmentation if you allocate and free blocks that are different sizes. You might be better off implementing a scheme where you have a few pools of different size buffers, and grab the memory you need from that not using pvPortMalloc() at all.

richard_damon wrote on Wednesday, December 15, 2010:

The heap2 implementation sounds like a bad fit for your application. After it allocates a block of a given size, even after it is freed that memory can not be used for a bigger block, so calling it repeatedly for varying sized blocks and then releasing them will lead to significant fragmentation of the heap. Using heap3 (i.e. malloc) might be better, and you could even use heap2 for the “FreeRTOS” heap and use malloc for this part (with the appropriate synchronization guards) if you really needed to.

You say that pre allocating a big enough buffer would be a big waste of space, but unless you have other parts of you program that that might be able to use this space, but only when you don’t need the biggest buffer for the data from flash, then you are NOT wasting the space, as you needed to reserve that amount of heap space for the allocation anyway. Using the heap for this may make sense if you can make sure that this and what ever else could use the space never need it at the same time, or can delay themselves a little bit if the memory is temporarily in use by the other piece (and this requires a lot of checks in the code, or mods to heap3.c to implement the delay). One big danger of the heap is you have to be very careful to avoid conditions that can fragment the heap and lock up your program, and it can be very hard to make sure you have defined enough heap for all conditions. You need to be especially careful about allocating “long term” block after you start allocating short term blocks as this greatly increases the danger of fragmentation.

anonymous wrote on Thursday, December 16, 2010:

Thanks for reply…

Actually, the allocation is just for a small amount time, when I need to present the data for the user and the user has done the selection. Then the data isn’t used any more.
My worries are too, not to have reserved enough for the heap, so the rest of the OS (Task, queue etc) get unstable.
And if i reserve enough memory for heap, I just as well could make my arrays big enough from the start. The RAM is reserved in either ways.

richard_damon: You say I could use the heap3 implementation and the heap2 for the FreeRTOS. Any special guidl line for using both? or is it just added the heap3.c and heap2.c to the project and build???


richard_damon wrote on Thursday, December 16, 2010:

You can’t use the heap2 and heap3 file at the same time, as they both define the same function. What you can do is use heap2 for FreeRTOS, and either make your own variation of heap3 with a different name for the functions, or just add the synchronization call yourself before/after each call to malloc and free. Note that, unless the library has hooks to make malloc itself thread safe, you also WILL need to protect any function you call that might call malloc or free itself.

As for FreeRtos memory allocation, it is normally considered good practice to initially allocate all your tasks, queue, buffers, etc at the beginning of a real time program and then just use them as you go. This lets you make sure you don’t run into issues with these things on the heap later. Using an allocate and keep forever avoids the build up of fragmentation in the heap.

If you do have some memory that does need to be allocated and released so different parts can share, it helps you if you can be sure that times exist fairly often when all of it is released so the heap fragments, or almost as good, all allocations (after a given point) have a limited lifetime, or you need to do some careful analysis, with knowledge of how the heap works to make sure that you don’t get into memory exhaustion because of fragmentation problems. You also need to code very defensively to handle out of memory conditions and try and do something smart on failure so you don’t just crash. Often this means some piece gracefully “fail” or delay themselves until more memory is obtainable.

petermeier wrote on Tuesday, December 21, 2010:

I have finished another heap implementation, due to the reason that iam working a lot with usb devices (where i have to allocate and free a lot of buffers at runtime). The main problem of heap2 is that its not re-using freed memory regions, it only appends new buffers. So if you run the following example, heap2 will stuck quite fast:

for(i=0;i<5000;i++) { p = alloc(i); free(p) }; It will stuck with 25k of heap at around 700 calls… This is sad…

So created my own heap manager.

Some examples: heap is ~400 bytes.

a1,a2,a3,a4 allocating each 100 bytes.
000…099 = a1,
100…199 = a2,
200…299 = a3,
300…399 = a4
Heap is full…

a2 and a3 are being freed:
000…099 = a1,
100…299 (free),
300…399 = a4
On heap are available 200 bytes…
a2 and a3 and a5, a6 are allocating each 50 bytes
000…099 = a1,
100…149 = a2,
150…199 = a3,
200…249 = a5,
250…299 = a6,
300…399 = a4
Now heap is full…
a1 and a2 are freed now
000…0149 (free),
150…199 = a3,
200…249 = a5,
250…299 = a6,
300…399 = a4
free space on heap now 149…

You can allocate and free stuff like that the whole night, there will be no fragmentation at all…
The heap will be cleaned up with every call of free() function. The malloc() function tires to find the best suitable gap to avoid memory waste.
In my system network buffers and application buffer are allocated at startup and will be never touched. The only changeable thing is the usb stack, and even there i have a sorted allocation/deallocation, so no need to think about fragmentation .
The only optimization i haven’t done yet, is to implement a XOR-linked list, so the free() function could take some time.
If someone is interested, tell me, and i can post the source here somewhere.

Kind regards,

tamirmichael wrote on Tuesday, July 03, 2012:

Hello Peter,

If you are still out there, it could be interesting to have a look at your memory manager !

Thanks in advance

petermeier wrote on Thursday, July 19, 2012:

Hello Michael,

i will have a look for the memory manager and will contribute it as soon as possible.