The CoreAudio framework uses a struct that is declared like this:
struct AudioBufferList
{
UInt32 mNumberBuffers;
AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements
};
typedef struct AudioBufferList AudioBufferList;
As far as I can tell, this is basically a variable length collection of AudioBuffer
structs. What is the 'correct' way to malloc such a struct?
AudioBufferList *list = (AudioBufferList *)malloc(sizeof(AudioBufferList));
Would this work?
I've seen all kinds of examples around the internet, like
calloc(1, offsetof(AudioBufferList, mBuffers) +
(sizeof(AudioBuffer) * numBuffers))
or
malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (numBuffers - 1))
That's not a variable length array; it's a 'struct hack'. The standard (since C99) technique uses a 'flexible array member', which would look this:
struct AudioBufferList
{
UInt32 mNumberBuffers;
AudioBuffer mBuffers[]; // flexible array member
};
One of the advantages of the FAM is that your questions are 'irrelevant'; the correct way to allocate the space for numBuffer
elements in the mBuffers
array is:
size_t n_bytes = sizeof(struct AudioBufferList) + numBuffer * sizeof(AudioBuffer);
struct AudioBufferList *bp = malloc(nbytes);
To answer your question, in practice both the malloc()
and the calloc()
will allocate at least enough space for the job, but nothing in any C standard guarantees that the code will work. Having said that, compiler writers know that the idiom is used and usually won't go out of their way to break it.
Unless space is incredibly tight, it might be simplest to use the same expression as would be used with a FAM; at worst, you have a little more space allocated than you absolutely need allocated. It will continue to work when you upgrade the code to use a FAM. The expression used in the calloc()
version would also work with a FAM member; the expression used in the malloc()
version would suddenly be allocating too little space.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With