一个柔性数组成员是否会增加结构体的大小?

14

我有一段如下的代码:

typedef struct
{    
    u32 count;
    u16 list[];   
} message_t;
...

message_t* msg = (message_t*)buffer;  
msg->count = 2;
msg->list[0] = 123;
msg->list[1] = 456;

size_t total_size = sizeof(*msg) + sizeof(msg->list[0]) * msg->count;  

send_msg( msg, total_size ); 

有问题的代码行是包含 sizeofs 的那一行。我不确定这是否是计算所需空间的正确方式。 sizeof(*msg) 是否已经包含了 list 成员的信息?

我可以使用我的编译器进行测试,但每个编译器在这种情况下是否都工作类似呢?


@Mitch Wheat:是的,你说得对。你的评论是标题问题的正确答案。给你点赞。 - SKi
2个回答

17

这是标准规定:

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


但是,帮助我们解释一下:这是否意味着 sizeof 结构体 + sizeof 列表 * 元素数量将给出“对象”的正确大小,就像 OP 计算的方式一样,还是这种方式可能会错过“奇怪”的填充? - ShinTakezou
谢谢。对于我的问题,标准答案的引用。我会接受这个答案。关于填充:因为“除了可能有比省略所暗示的更多的尾部填充”,可能意味着没有灵活数组成员时sizeof(struct)可能会不同。但是在我的情况下,这不是一个问题。 - SKi
7
假设在一个需要 int 四字节对齐的平台上,有一个包含五个 char 字段和一个 int[] 的结构体。如果没有灵活成员,结构体的大小将为五个字节,不需要对齐;而有了它,结构体的大小将为八个字节,并且必须在四字节边界上对齐。 - supercat

1

你的例子是可行的,因为C语言没有动态增加元素的数组。所以*msg的大小是sizeof u32 +填充,如果有的话,但它不会计入列表成员,当你“分配”缓冲区并想要知道该“对象”的实际大小时,你必须自己考虑它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接