可能重复:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
Extra bytes when declaring a member of a struct as uint32_t
出于某种原因,sizeof
运算符会为此结构返回一个虚假大小(48
而不是40
):
typedef struct mbdb_file_info {
uint16_t mode;
uint32_t unk0;
uint32_t unk1;
uint32_t user_id;
uint32_t group_id;
uint32_t time0;
uint32_t time1;
uint32_t time2;
uint64_t length;
uint8_t flag;
uint8_t property_count;
} mbdb_file_info;
所以这是一个简单的测试:
printf("%ld %ld %ld %ld: %ld", sizeof(uint8_t),
sizeof(uint16_t),
sizeof(uint32_t),
sizeof(uint64_t),
sizeof(mbdb_file_info));
打印哪些:
1 2 4 8:48
这是怎么发生的?如果您将所有尺寸添加到一起,则会获得40
,而不是48
。 48
来自何处?
如果它是一些奇怪的x86-64
perk,我如何确保结构的所有字段占用我想要它们占用的数量(我正在为这个结构投射一堆字节) )?
答案 0 :(得分:3)
编译器可能会在struct的中间附加一些字节,以便对齐struct成员。结构的大小至少是其成员大小的总和,但不限于此。
答案 1 :(得分:3)
您还可以通过重新排序结构成员来摆脱填充。例如,如果你声明64位,然后是32位,然后是16位,然后是8位,那么它将自然对齐并且没有额外的填充字节。
答案 2 :(得分:1)
由于结构填充(不确定这里的术语是什么)。最大的领域是64位,所以一切都按照它排列。所以,我们有:
typedef struct mbdb_file_info {
uint16_t mode; // 16 +
uint32_t unk0; // 32 = 48, so add 16 more to align to 64bit;
uint32_t unk1; // this
uint32_t user_id; // and this give 64bits ;
uint32_t group_id; // again this
uint32_t time0; // plus this - 64bits;
uint32_t time1; // this
uint32_t time2; // and this = 64bit ;
uint64_t length; // this is 64 by itself
uint8_t flag; // this
uint8_t property_count; // +this is 16, add 48 for the alignment
} mbdb_file_info; // when you sum all bits (+ the additional for padding)
// you have exactly 48B
答案 3 :(得分:0)
对齐。某些数据类型在某些边界处对齐(读取:可被2整除的地址,例如16),这取决于体系结构,这会导致结构中的填充。
有一些编译器选项可以抑制此行为,and the gcc documentation tells you how to use the aligned
attribute就可以了。
答案 4 :(得分:0)
这称为结构填充用于对齐。
可能发生的是8位和16位值填充到32位,整个结构填充为机器字大小的倍数(8)。