如何malloc包含可变长度数组的结构?

Jaw*_*wap 4 c arrays malloc struct core-audio

CoreAudio框架使用如下声明的结构:

struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements
};
typedef struct AudioBufferList  AudioBufferList;
Run Code Online (Sandbox Code Playgroud)

据我所知,这基本上是一个可变长度的AudioBuffer结构集合.malloc这样一个结构的'正确'方法是什么?

AudioBufferList *list = (AudioBufferList *)malloc(sizeof(AudioBufferList));
Run Code Online (Sandbox Code Playgroud)

这会有用吗?

我在互联网上看过各种各样的例子,比如

calloc(1, offsetof(AudioBufferList, mBuffers) +
          (sizeof(AudioBuffer) * numBuffers))
Run Code Online (Sandbox Code Playgroud)

要么

malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (numBuffers - 1))
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 9

那不是一个可变长度数组; 这是一个'结构黑客'.标准(自C99)技术使用"灵活的阵列成员",看起来如下:

struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[]; // flexible array member
};
Run Code Online (Sandbox Code Playgroud)

FAM的一个优点是你的问题"无关紧要"; 为数组中的numBuffer元素分配空间的正确方法mBuffers是:

size_t n_bytes = sizeof(struct AudioBufferList) + numBuffer * sizeof(AudioBuffer);
struct AudioBufferList *bp = malloc(nbytes);
Run Code Online (Sandbox Code Playgroud)

为了回答你的问题,在实践中,它malloc()calloc()将为作业分配至少足够的空间,但任何C标准都没有保证代码可以工作.话虽如此,编译器编写者知道使用了这个习惯用法,并且通常不会破坏它.

除非空间非常紧张,否则使用与FAM一样的表达式可能是最简单的; 在最坏的情况下,你分配的空间比你绝对需要的多一些.升级代码以使用FAM时,它将继续工作.calloc()版本中使用的表达式也适用于FAM成员; malloc()版本中使用的表达式会突然分配太少的空间.