为什么某些struct使用单个元素数组,如下所示:
typedef struct Bitmapset
{
int nwords;
uint32 words[1];
} Bitmapset;
为了方便以后的动态分配?
答案 0 :(得分:16)
总之,是的。
基本上,C99的方法是使用flexible array member:
uint32 words[];
一些C99之前的编译器让你逃脱:
uint32 words[0];
但是保证它在所有编译器中工作的方法是:
uint32 words[1];
然后,无论如何声明,您都可以使用以下内容分配对象:
Bitmapset *allocate(int n)
{
Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof(p->words[0]));
p->nwords = n;
return p;
}
虽然为了获得最佳效果,您应该使用size_t
代替int
。
答案 1 :(得分:6)
这通常允许对可变大小的结构实例进行惯用访问。考虑到您的示例,在运行时,您可能有一个在内存中布局的Bitmapset,如下所示:
-----------------
| nwords | 3 |
| words[0] | 10 |
| words[1] | 20 |
| words[2] | 30 |
-----------------
所以你最终得到一个运行时变量的uint32“悬挂”在结构的末尾,但是可以访问它们就好像它们在结构中内联定义一样。这基本上是(ab)使用C不进行运行时数组边界检查以允许您编写如下代码的事实:
for (int i = 0; i < myset.nwords; i++) {
printf("%d\n", myset.words[i]);
}