C结构大小不一致

可能重复:
如何找到结构的大小?
结构的内存大小不同?

我正在使用以下结构进行网络通信,它在两者之间创建了许多不必要的字节。

它给出了与预期的8字节不同的大小。

struct HttpPacket { unsigned char x1; union { struct { unsigned char len; unsigned short host; unsigned char content[4]; } packet; unsigned char bytes[7]; unsigned long num; } 

并且以下给出了不同的大小,即使我从联合中删除了一个字段

 struct HttpPacket { unsigned char x1; union { struct { unsigned char len; unsigned short host; unsigned char content[4]; } packet; unsigned long num; } 

另外,一个更明显的例子

 struct { unsigned char len; unsigned short host; unsigned char content[4]; } packet; 

它的大小为8而不是7.我再添加一个字段,它仍然给出相同的大小

 struct { unsigned char EXTRAADDEDFIELD; unsigned char len; unsigned short host; unsigned char content[4]; } packet; 

有人可以帮忙解决这个问题吗?

更新:我需要在传输数据包时保持格式,所以我想跳过这些填充

有没有听说过对齐和填充 ?

基本上,为了确保快速访问,某些类型必须在内存地址的某些边界上。
这称为对齐。

为此,允许编译器将字节插入到数据结构中以实现该对齐。
这称为填充。

C不保证struct的大小。 允许编译器按顺序排列成员。 通常,就像在这种情况下一样,它会使大小字对齐,因为这在大多数机器上都是最快的。

默认情况下,结构字段在自然边界上对齐。 例如,一个4字节的字段将从4字节边界开始。 编译器插入填充字节来实现此目的。 您可以使用#pragma pack(0)或其他类似的编译器指令来避免填充

如果您有一个C99编译器并且可以使用“新”固定宽度类型:创建一个uint8_t数组并自己在成员中进行分离。

 uint8_t data[8]; x1 = data[0]; len = data[1]; host = data[2] * 256 + data[3]; /* big endian */ content[0] = data[4]; content[1] = data[5]; content[2] = data[6]; content[3] = data[7]; /* ... */ 

如果您可以依赖CHAR_BIT为8,则可以在C89中执行相同的步骤。