Thanks, glad to know it won't do something unexpected with the heap allocations.
Now, the primary reason why I'm not keen on statically allocating a fixed-size array is because it would take up a significant chunk of memory. If I want to cater for a maximum of 256 callback functions, it will require 512 bytes of memory. My microcontroller only has 2KB of RAM, so that would be 25% of all memory! And, in fact, I will not only be storing a 16 bit pointer, but also an 8-bit integer with each that notes how many argument values are to be passed to the function, which would make it 768 bytes! I don't think I can afford to reserve that much memory.
I understand that I could just simply size my fixed array to only what is required, but this is where my secondary reason comes in: that I'm trying to make this a more generic solution as part of a module that will be utilised again elsewhere in future, where there may be a wholly different set of callback functions. I just want to make it so that the only thing I have to worry about is making a call to something like a register_callback() function, and that's it. No messing about re-defining constants, etc.
I'm not too worried about safety, as the allocations will be a one-time operation on start-up, and will never be free()-ed.
Here's another question: can I make any assumptions about the default value of any memory allocated with realloc()? Given that calloc() exists, I would assume that realloc() does not do any initialisation of allocated memory, and so as a worst case scenario, might the allocated memory contain random garbage?
That would kind of complicate the scenario where I am allocating memory for a sparsely-populated array, because then any unpopulated op-code pointers in my array would not be null, and thus indistinguishable from a populated one. I would have to write some code to specifically zero-out any 'gaps' in the allocation.