代码之家  ›  专栏  ›  技术社区  ›  fatdragon

结构具有并集时的意外大小

  •  3
  • fatdragon  · 技术社区  · 7 年前

    我正在尝试验证结构的大小。出于某些原因,它给了我一个18字节的大小,而不是预期的14字节(联合体的最大值应该是8+2+2=12字节)。有人能帮我吗?

    typedef struct __attribute__((__packed__)) def
    {
            union {
                    double x;   /* 8 bytes */
                    char *y;    /* 8 bytes as for 64-bit system */
                    struct {
                            struct def *array; /* 8 bytes */
                            unsigned short a;  /* 2 bytes */
                            unsigned short b;  /* 2 bytes */
                    } z;
            } w;
            unsigned short v;  /* 2 bytes */
    } DEF, *DEFP;
    
    int main(int argc, char **argv) {
            printf("size of DEF = %lu\n", sizeof(DEF));
            printf("size of unsigned short = %lu\n", sizeof(unsigned short));
            printf("size of struct def * = %lu\n", sizeof(struct def *));
            printf("size of char * = %lu\n", sizeof(char *));
            printf("size of double = %lu\n", sizeof(double));
    }
    

    下面是我运行它时显示的内容:

    $ gcc test.c && ./a.out
    size of DEF = 18
    size of unsigned short = 2
    size of struct def * = 8
    size of char * = 8
    size of double = 8
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   alk    7 年前

    __attribute__((__packed__)) struct def 只有它不打包匿名 struct 匿名者内部 union 在…内 结构定义 .

    所以很可能那两个成员

                       unsigned short a;  /* 2 bytes */
                       unsigned short b;  /* 2 bytes */
    

    “使用”4但2个字节。


    与您的问题无关:C授权打印 size_t s使用 z 长度修改器 :

     printf("size of DEF = %zu\n", sizeof (DEF));
    
        2
  •  2
  •   Art    7 年前

    写作:

    struct foo {
        struct bar {
            ...
        } x;
    };
    

    与书写没有区别:

    struct bar { ... };
    struct foo {
        struct bar x;
    };
    

    为什么这很重要?这很重要,因为在第二个示例中,应该很清楚为什么要应用 foo 不自动应用于 bar . 这意味着您的外部结构将被打包,但这不会改变组件的含义。

    您拥有的内部结构不会被打包,很明显,如果它遵循通常的对齐规则,那么大多数架构遵循的大小将是其最严格对齐的成员(指针)的倍数。因此,联合体内部结构的大小将是16,而不是您假设的12。这意味着工会的规模也将达到16个。