How to copy a structure containing a variable length array?

The CoreAudio infrastructure uses a structure that is declared as follows:

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 collection of variable lengths AudioBufferstructs. What is the “right” way to build such a structure?

AudioBufferList *list = (AudioBufferList *)malloc(sizeof(AudioBufferList));

Will this work?

I have seen all kinds of examples on the Internet, for example

calloc(1, offsetof(AudioBufferList, mBuffers) +
          (sizeof(AudioBuffer) * numBuffers))

or

malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (numBuffers - 1))
+4
source share
3 answers

It is not an array of variable length; this is a "structural hack". The standard (starting with C99) method uses a "flexible array element" that will look like this:

struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[]; // flexible array member
};

FAM , ""; numBuffer mBuffers:

size_t n_bytes = sizeof(struct AudioBufferList) + numBuffer * sizeof(AudioBuffer);
struct AudioBufferList *bp = malloc(nbytes);

, malloc() calloc() , C , . , - , , .

, , FAM; , . , , FAM. , calloc(), FAM; , malloc(), .

+9

, , . , 9 AudioBuffers,

list = malloc( sizeof *list + 9 * sizeof list->mBuffers[0] );

( undefined, mBuffers, 1), .

, , malloc. , , .

, ; 1 AudioBufferList ( malloc ). " ".

+3

- CAAudioBufferList::Create, Apple, CAAudioBufferList.cpp Core Audio Utility. :

https://developer.apple.com/library/mac/samplecode/CoreAudioUtilityClasses/Introduction/Intro.html

:

AudioBufferList*    CAAudioBufferList::Create(UInt32 inNumberBuffers)
{
    UInt32 theSize = CalculateByteSize(inNumberBuffers);
    AudioBufferList* theAnswer = static_cast<AudioBufferList*>(calloc(1, theSize));
    if(theAnswer != NULL)
    {
        theAnswer->mNumberBuffers = inNumberBuffers;
    }
    return theAnswer;
}

void    CAAudioBufferList::Destroy(AudioBufferList* inBufferList)
{
    free(inBufferList);
}

UInt32  CAAudioBufferList::CalculateByteSize(UInt32 inNumberBuffers)
{
    UInt32 theSize = SizeOf32(AudioBufferList) - SizeOf32(AudioBuffer);
    theSize += inNumberBuffers * SizeOf32(AudioBuffer);
    return theSize;
}
+2

Source: https://habr.com/ru/post/1531972/