这是C99代码:
typedef struct expr_t
{
int n_children;
foo data; // Maybe whatever type with unknown alignment
struct expr_t *children[];
} expr_t;
现在,我该如何分配内存?
expr_t *e = malloc (sizeof (expr_t) + n * sizeof (expr_t *));
或
expr_t *e = malloc (offsetof (expr_t, children) + n * sizeof (expr_t *));
sizeof
是否保证可以使用具有灵活数组成员的类型(GCC接受它)?
答案 0 :(得分:8)
expr_t *e = malloc (sizeof (expr_t) + n * sizeof (expr_t *));
在C99中定义明确。来自C99规范6.7.2.1.16:
作为一种特殊情况,结构的最后一个元素有多个 命名成员可能具有不完整的数组类型;这叫做a 灵活的阵列成员。在大多数情况下,灵活的阵列成员 被忽略了。特别是,结构的大小就像是 柔性阵列成员被省略,除了它可能有更多 尾随填充比遗漏意味着暗示。
答案 1 :(得分:4)
如果编译器接受具有灵活数组成员的结构声明,则该结构的sizeof
运算符应该产生结构的大小,就像灵活数组成员不存在一样。
这种结构的正确分配是:
expr_t *e = malloc (sizeof(expr_t) + n * sizeof(struct expr_t *));
即使编译器不支持灵活的数组成员,您仍然可以执行此操作。只需将结构的数组成员声明为1
,然后分配n - 1
个项而不是n
。