好的,我的C ++程序中有一个结构,如下所示:
struct thestruct
{
unsigned char var1;
unsigned char var2;
unsigned char var3[2];
unsigned char var4;
unsigned char var5[8];
int var6;
unsigned char var7[4];
};
当我使用这个结构时,在“var6”之前添加3个随机字节,如果我删除“var5”它仍然在“var6”之前,所以我知道它总是在“var6”之前。
但是如果我删除“var6”那么3个额外字节就消失了。
如果我只使用带有int的结构,则没有额外的字节。
所以unsigned char和int之间似乎存在冲突,我该如何解决?
答案 0 :(得分:6)
编译器可能正在使用其默认对齐选项,其中 x 大小的成员在内存边界上对齐,可以被 x 整除。
根据您的编译器,您可以使用#pragma
directive来影响此行为,例如:
#pragma pack(1)
将关闭Visual C ++中的默认对齐方式:
指定要用于打包的值(以字节为单位)。 n 的默认值为8.有效值为1,2,4,8和16.成员的对齐方式将位于 n <的倍数的边界上/ em>或成员大小的倍数,以较小者为准。
请注意,出于低级CPU性能原因,通常最好尝试对齐数据成员,使其落在对齐的边界上。某些CPU架构需要对齐,而其他(例如Intel x86)容忍错位,性能下降(有时非常显着)。
答案 1 :(得分:5)
您的数据结构为aligned,因此您的int属于单词边界,对于您的目标可能是32位或64位。
您可以像这样重新组织结构,以便不会发生这种情况:
struct thestruct
{
int var6;
unsigned char var1;
unsigned char var2;
unsigned char var3[2];
unsigned char var4;
unsigned char var5[8];
unsigned char var7[4];
};
答案 2 :(得分:4)
你在谈论填充字节吗?这不是一个错误。在C ++标准允许的情况下,编译器会添加填充以保留成员aligned。这是某些架构所必需的,并将大大提高其他架构的性能。
答案 3 :(得分:0)
你遇到了字节对齐问题。编译器正在添加填充以对齐字节。请参阅this维基百科文章。
答案 4 :(得分:0)
阅读data structure alignment。从本质上讲,根据编译器和编译选项,您可以调整到不同的2次幂。
为避免这种情况,请在单字节(有符号或无符号 char )项之前移动多字节项( int 或指针) - 尽管它可能仍然存在在之后的最后一项。
答案 5 :(得分:0)
在重新排列您在struct
内声明数据成员的顺序时,应该强调的是,使用#pragma
来覆盖默认对齐方式,这是一个坏主意除非你确切知道你在做什么。根据您的编译器和体系结构,尝试访问未对齐的数据,特别是通过将地址存储在指针中并稍后尝试取消引用它,可以轻松地提供可怕的总线错误或其他未定义的行为。