Page 1 of 1

Malloc - allocating memory

Posted: Tue Oct 02, 2018 7:02 pm
by mnf
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.
(11.76 KiB) Downloaded 120 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.