【问题标题】:C struct sizes inconsistence [duplicate]C结构大小不一致[重复]
【发布时间】:2012-01-22 06:51:23
【问题描述】:

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

即使我正在从联合中删除字段,Following 也会给出不同的大小

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;

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

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

【问题讨论】:

  • 我需要在传输数据包时保持格式,所以我想跳过这些填充
  • 在 XCode 4 LLVM 编译器上需要这个
  • 但是,我需要 XCode 4 新 LLVM 编译器的解决方案。

标签: c++ c struct sizeof


【解决方案1】:

C 不保证struct 的大小。编译器可以根据需要排列成员。通常,在这种情况下,它会使大小与字对齐,因为这在大多数机器上是最快的。

【讨论】:

【解决方案2】:

听说过alignment and padding吗?

基本上,为了确保快速访问,某些类型必须位于特定的内存地址范围内。
这称为对齐。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 如何在 LLVM XCode 4 编译器上做到这一点
    【解决方案4】:

    如果您有 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 中遵循相同的过程。

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 1970-01-01
      • 2021-07-09
      • 2018-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多