7

这是 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 接受它)?

4

2 回答 2

10

expr_t *e = malloc (sizeof (expr_t) + n * sizeof (expr_t *));在 C99 中定义良好。从 C99 规范 6.7.2.1.16:

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员。在大多数情况下,灵活数组成员被忽略。特别是,结构的大小就像省略了柔性数组成员一样,只是它可能具有比省略所暗示的更多的尾随填充。

于 2012-10-01T20:58:53.080 回答
4

如果编译器接受具有灵活数组成员的结构的声明,则该结构的sizeof运算符应该产生结构的大小,就好像灵活数组成员不存在一样。

这种结构的正确分配是:

expr_t *e = malloc (sizeof(expr_t) + n * sizeof(struct expr_t *));

即使编译器不支持灵活的数组成员,您仍然可以使用此技巧。只需将结构的数组成员声明为大小1,然后分配n - 1项目而不是n.

于 2012-10-01T21:00:48.850 回答