可能重复:
How do I find the size of a struct?
Struct varies in memory size?
我正在使用以下结构进行网络通信,它会在它们之间创建大量不必要的字节。
它提供的大小与预期的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;
有人可以帮忙解决这个问题吗?
更新:我需要在传输数据包时保留格式,所以我想跳过这些填充
答案 0 :(得分:10)
C不保证struct
的大小。允许编译器按照它想要的顺序排列成员。通常,就像在这种情况下一样,它会使大小字对齐,因为这在大多数机器上都是最快的。
答案 1 :(得分:7)
有没有听说过alignment and padding?
基本上,为了确保快速访问,某些类型必须在内存地址的某些范围内 这称为对齐。
为了实现这一点,允许编译器将字节插入到数据结构中以实现该对齐 这称为填充。
答案 2 :(得分:2)
默认情况下,结构字段在自然边界上对齐。例如,一个4字节的字段将从4字节边界开始。编译器插入填充字节来实现此目的。您可以使用#pragma pack(0)或其他类似的编译器指令
来避免填充答案 3 :(得分: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中的相同步骤进行操作。