开发者

C++ struct containing unsigned char and int bug

Ok i have a struct in my C++ program that is like this:

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];
};

When i use this struct, 3 random bytes get ad开发者_运维问答ded before the "var6", if i delete "var5" it's still before "var6" so i know it's always before the "var6".

But if i remove the "var6" then the 3 extra bytes are gone.

If i only use a struct with a int in it, there is no extra bytes.

So there seem to be a conflict between the unsigned char and the int, how can i fix that?


The compiler is probably using its default alignment option, where members of size x are aligned on a memory boundary evenly divisible by x.

Depending on your compiler, you can affect this behaviour using a #pragma directive, for example:

#pragma pack(1)

will turn off the default alignment in Visual C++:

Specifies the value, in bytes, to be used for packing. The default value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.

Note that for low-level CPU performance reasons, it is usually best to try to align your data members so that they fall on an aligned boundary. Some CPU architectures require alignment, while others (such as Intel x86) tolerate misalignment with a decrease in performance (sometimes quite significantly).


Your data structure being aligned so that your int falls on word boundries, which for your target might be 32 or 64 bits.
You can reorganize your struct like so so that this won't happen:

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];
};


Are you talking about padding bytes? That's not a bug. As allowed by the C++ standard, the compiler is adding padding to keep the members aligned. This is required for some architectures, and will greatly improve performance for others.


You're having a byte alignment problem. The compiler is adding padding to align the bytes. See this wikipedia article.


Read up on data structure alignment. Essentially, depending on the compiler and compile options, you'll get alignment onto different powers-of-2.

To avoid it, move multi-byte items (int or pointers) before single-byte (signed or unsigned char) items -- although it might still be there after your last item.


While rearranging the order you declare data members inside your struct is fine, it should be emphasized that overriding the default alignment by using #pragmas and such is a bad idea unless you know exactly what you're doing. Depending on your compiler and architecture, attempting to access unaligned data, particularly by storing the address in a pointer and later trying to dereference it, can easily give the dreaded Bus Error or other undefined behavior.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜