C 零长度数组的结构填充
在结构中使用可变长度数组的最佳实践是什么? 说 在带有GCC4.8的x86_64机器上,我得到了C 零长度数组的结构填充,c,C,在结构中使用可变长度数组的最佳实践是什么? 说 在带有GCC4.8的x86_64机器上,我得到了 sizeof(foo_t) == 8, but offsetof(foo_t, data) == 6 看起来有点不同,在data_len之后没有填充,但是结构有填充。 我是否应该将最大的成员放在最后以避免这种情况?i、 e typedef struct foo_s { uint16_t data_len; uint32_t data_type; uint8_t data[];
sizeof(foo_t) == 8, but
offsetof(foo_t, data) == 6
看起来有点不同,在data_len之后没有填充,但是结构有填充。
我是否应该将最大的成员放在最后以避免这种情况?i、 e
typedef struct foo_s {
uint16_t data_len;
uint32_t data_type;
uint8_t data[];
} foo_t;
使用var len数组的最佳实践是什么?除非您有特定的理由希望
数据
是4字节对齐的(如果是,为什么是uint8
?),否则第一种方法比较可取,因为它会为您节省几个字节。对于这样的可变长度结构,sizeof
报告的值实际上并不相关,正是出于这个原因。如果您决定为它分配sizeof(foo\u t)+data\u len
字节,那么您将浪费几个字节,但无论如何,您会在第二个结构定义中的填充中浪费它们。如果您想在不牺牲对齐的情况下打包结构,那么是的:最好的选择是按降序或升序排列元素。数组必须是最后一个元素,因此在这里,最好的选择是降序(请注意,赢的大小很小,只有当您有一个大的结构数组时才重要,但使用灵活的数组成员时,您不能有一个结构数组).sizeof返回8,因为当结构是数组的元素时,需要保持uint32\u t仍然对齐。当然,您永远不会将它们存储在数组中,所以请忽略这一点。您对malloc的调用只使用offsetof()+数组大小。是的,我不太担心对齐,更担心的是如果用户以不同的方式计算大小,那么整个大小的差异,特别是当有一个foo_t数组打包到缓冲区时。如果缓冲区中有一个完整的foo_t数组,那么您无论如何都需要填充分配,因此,有更多的理由使用第一种形式。你能详细说明一下“我需要填充分配”吗?谢谢。如果您的体系结构要求在四字节边界上填充int,那么您不能(比如)为可变长度成员分配五个字节,并从下一个字节开始下一个结构;您需要将总大小填充到int
可以使用的大小。当然,很少看到可变长度数组将结构打包在一起,所以这种情况很少出现。
typedef struct foo_s {
uint16_t data_len;
uint32_t data_type;
uint8_t data[];
} foo_t;