Malloc - allocating memory

Tips, Tricks and methods for programming, learn ways of making your programming life easier, and share your knowledge with others.

Moderators: Benj, Mods

mnf
Valued Contributor
Valued Contributor
Posts: 530
Joined: Wed May 31, 2017 11:57 am
Has thanked: 52 times
Been thanked: 294 times
Contact:

Malloc - allocating memory

Postby mnf » Tue Oct 02, 2018 7:02 pm

I've added this as a sub-topic - it might be useful to some.

A little background:
I was looking to allocate some dynamic memory to allow a macro to take variable length parameters (arrays) - make a copy (algorithm is destructive) process the data and then return the allocated memory.
All arrays are passed by reference in Flowcode - which is usually what is required for memory and performance issues. Strings have the 'make local copy' option - which creates a copy of the data local to the macro - thus any changes do not affect the caller. However - whereas any length array or string can be passed to a macro the local copy of the string will always be the same length as specified in the macro definition (ie s[20] - will only make a 20 character copy whatever length string is passed to the macro)

So: C allows dynamic memory allocation using malloc (or calloc - we'll mention later). The syntax is simple

Code: Select all

x = malloc(n);
where n specifies the number of bytes to allocate. Note that it is the user's responsibility to free the memory when no longer needed (using free(x)) - otherwise memory loss can occur - eventually leading to the mcu running out of RAM.

There is a catch. Flowcode doesn't have the concept of pointers (at least not in the sense we need here) - and so we can't store values to the allocated memory without using some simple C code. I've simply assigned them to an int.
Here is a simple program that allocates a linked list in memory - walks it (displaying the values) then deletes it. And then repeats.

linked.fcfx
(11.76 KiB) Downloaded 52 times

Note that this uses a 16bit pointer for the data - on MCUs blessed with more memory you might need to go to 32bits.
Possibly - some MCUs might like data writes/reads to be word or long word aligned - although it is slightly more fiddly you can evade this by either writing all data in the appropriate size chunks - or by splitting it into bytes and writing a byte at a time.
I'm also assuming that all toolset's compilers support this.

As in the demo - malloc returns 0 when it can't allocate the memory. Note that each allocation also includes a 2 byte length (stored immediately before the allocated space) - which is used by free. (Mess with this value if you like crashing programs)
calloc - clears the allocated memory before returning. The syntax is slightly different -

Code: Select all

calloc(el_size, no_els)
- so el_size is 1 for byte, 2 for int etc (or you can use sizeof(int) etc) and no_els is the number of elements to allocate. So

Code: Select all

x = calloc(sizeof(int), 16)
will allocate 32 bytes (on an MCU with a 2 byte int)

And - please add pointers to FC8.1 and also structs would be good too :) There is a whole world of exciting and useful data structures made possible by them.

Martin
These users thanked the author mnf for the post (total 5):
medelec35 (Tue Oct 02, 2018 8:16 pm) • petesmart (Tue Oct 02, 2018 9:59 pm) • Steve (Wed Oct 03, 2018 8:49 am) • Benj (Wed Oct 03, 2018 9:35 am) • jgu1 (Wed Oct 03, 2018 4:37 pm)
Rating: 26.32%