结构体大小不符合预期

4

我有一个这样定义的结构体:

typedef struct _CONFIGURATION_DATA {
    BYTE configurationIndicator;
    ULONG32 baudRate;
    BYTE stopBits;
    BYTE parity;
    BYTE wordLength;
    BYTE flowControl;
    BYTE padding;
} CONFIGURATION_DATA;

根据我的计算,该结构体长度为10字节。但是sizeof报告它的长度为16字节?有人知道原因吗?

我正在使用Windows DDK中的构建工具进行编译。


强制对齐某种形式? - jldupont
请注意:结构体的大小可能不等于其成员大小之和;实现允许在成员之间和最后一个成员之后插入填充。请<b>始终</b>通过名称访问成员,而不是通过偏移量访问,因为偏移量可能会在编译器版本和供应商之间发生变化。 - Thomas Matthews
4个回答

12

对齐。

使用

#pragma pack(1)

...在此处添加结构体...

#pragma pack()

我还建议重新排序内容,并在必要时用保留字节进行填充,以便多字节整数类型更好地对齐。这将使CPU处理速度更快,并使您的代码更小。


1
只有在有充分理由的情况下才这样做--许多架构都不允许未对齐的访问(因此编译器必须使用字节加载和保存以确保安全),大多数还会引入性能损失。 - Andrew Aylett
正确。但是我期望编译器在架构不支持时生成适当的指令来访问未对齐的整数类型。这是访问文件、通信和其他IO中的二进制数据的常见模式。相反,如果您没有明确指定对齐方式,请避免编写结构,因为它会随着编译器版本/设置而改变。 - Pavel Radzivilovsky
实际上,我需要这样打包的原因是因为它将被写入套接字,通信规范要求10字节的消息。 - Alistair Evans
@Pavel:我肯定不会“期望”那样的情况。你只是因为习惯了x86硬件而变得很挑剔。编写在最轻微的刺激下就会崩溃的程序也是一种“常见模式”。 - jalf
@jalf,AAT:所谓“expect”,我指的是这个:“编译器是适当的抽象层,处理对齐不幸的地方。”例如,紧密打包的结构成员应该像__unaligned一样由MSVC处理。所有其他编译器都应该插入位操作,因为在这种特殊情况下,编译器可以知道指针可能未对齐。 - Pavel Radzivilovsky
显示剩余2条评论

4

将元素的顺序改变。从ULONG开始,接着是BYTEs。这样可以提高结构体在内存中的对齐方式。


3

这是因为填充的原因,因为在您的平台上,显然必须将ULONG32对齐到4字节边界。由于结构体的开头和结尾也必须对齐,因此第一个和最后一个BYTE都将填充3个字节。


2
你测量到的额外大小是编译器引入的填充。假设你正在使用32位系统,所以在“configurationIndicator”和“baudRate”之间会有3个字节的填充,在结构体末尾还会有3个字节的填充。

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