2014-08-27 92 views
2

在结构中使用可变长度数组的最佳做法是什么? 说零长度数组结构填充

typedef struct foo_s { 
    uint32_t data_type; 
    uint16_t data_len; 
    uint8_t data[]; 
} foo_t; 

在一个x86_64的机器用GCC 4.8,我得到

sizeof(foo_t) == 8, but 
offsetof(foo_t, data) == 6 

看起来就像是有差别的存在,DATA_LEN后无填充,但填充的结构。 我是否应该始终保持最大的成员以避免这种情况?即

typedef struct foo_s { 
    uint16_t data_len; 
    uint32_t data_type; 
    uint8_t data[]; 
} foo_t; 

什么是使用var len数组的最佳做法?

+1

sizeof返回8,因为当struct是一个数组的元素时,需要保持uint32_t仍然对齐。当然,你从来没有**将它们存储在一个数组中,所以忽略它。您对malloc的调用仅使用offsetof()+数组大小。 – 2014-08-27 23:23:10

回答

1

除非你有特别的理由要求data为4字节对齐(如果是这样,为什么它是uint8?),第一个是适度的,因为它会为你节省几个字节。对于像这样的可变长度结构,由于这个原因,sizeof报告的值并不真正相关。如果你决定为它分配sizeof(foo_t) + data_len字节,那么你会浪费几个字节,但是无论如何你会浪费它们填充你的第二个结构定义。

+0

是的,如果用户以不同的方式计算大小,特别是当有一个foo_t打包到缓冲区中时,我不太担心对齐,更多的是关于整个大小差异。 – wei 2014-08-27 23:32:33

+0

如果在缓冲区中存在它们的整个数组,那么无论如何您都需要填充分配,因此更有理由使用第一种形式。 – Sneftel 2014-08-28 07:11:51

+0

能否详细说明“我需要填充分配”?谢谢。 – wei 2014-08-29 21:12:02

1

如果你想打包你的结构而不牺牲对齐,那么是的:最好的选择是按递减顺序或递增顺序排列元素。数组必须是最后一个元素,所以这里最好的选择是递减顺序(请注意,win的大小很小,只有当你有大量的结构体时才重要,但是对于一个灵活的数组成员,你不能拥有结构数组)。