包含unsigned char和int bug的C ++ struct

时间:2010-05-30 04:17:34

标签: c++ struct byte

好的,我的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之间似乎存在冲突,我该如何解决?

6 个答案:

答案 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来覆盖默认对齐方式,这是一个坏主意除非你确切知道你在做什么。根据您的编译器和体系结构,尝试访问未对齐的数据,特别是通过将地址存储在指针中并稍后尝试取消引用它,可以轻松地提供可怕的总线错误或其他未定义的行为。