C结构大小不一致

时间:2011-12-16 19:47:09

标签: c++ c struct sizeof

  

可能重复:
  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;

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

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

4 个答案:

答案 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中的相同步骤进行操作。