【问题标题】:Size of a struct seemingly incorrect? [duplicate]结构的大小看似不正确? [复制]
【发布时间】:2016-06-06 07:00:19
【问题描述】:

我在 C 中声明了这个结构。当我调用sizeof(struct pixel) 时,我被告知这个结构的大小是 12 字节,而我希望它是 7 个字节(1 个用于字符,4 个用于 int)。为什么会这样?

结构:

   struct pixel {
        unsigned char red;
        unsigned char green;
        unsigned int alpha;
        unsigned char blue;
    };

【问题讨论】:

标签: c memory size


【解决方案1】:

正如其他几位用户所指,是填充问题。见this
我认为你可以减少这个结构的更少是 8 个字节(在 x86 处理器中),或者将 alpha 字段放在开头或结尾

【讨论】:

    【解决方案2】:

    这个想法是为了速度和缓存考虑,操作数应该从与其自然大小对齐的地址中读取。

    struct pixel {
        unsigned char red;   // 0
        unsigned char green; // 1
        unsigned int alpha;  // 4 (gotta skip to an aligned offset)
        unsigned char blue;  // 8 (then skip 9 10 11)
    };
    
    // next offset: 12
    

    x86 架构始终能够获取未对齐的地址。但是,它的速度较慢,并且当未对齐与两个不同的缓存行重叠时,它会驱逐两个缓存行,而对齐的访问只会驱逐一个。

    某些架构实际上必须捕获未对齐的读取和写入,以及 ARM 架构的早期版本(演变为当今所有移动 CPU 的架构)......好吧,它们实际上只是为这些返回了错误的数据。

    所以,对齐很重要。

    【讨论】:

    • 感谢您的快速回复。作为一个快速跟进,无论如何,这个结构是否严格小于 8 个字节(我可以轻松地将它减少到 8 个)
    • 但这只会返回 8 作为大小。有没有办法我可以 - 故意 - 获得 7 个字节?
    • @tanishqdubey 如果是 GCC:pragma pack。 MSVC 也应该支持它。
    • @Youka 的建议是正确的。参见,例如,stackoverflow.com/questions/3318410/pragma-pack-effect
    【解决方案3】:

    在 C 中,结构成员是对齐的,以实现更快、更安全的内存访问。您的默认对齐方式是 4,因此在 redgreen 之后跟随 2 个填充字节(4 字节块完成),然后是 4 字节的 alpha 和最后一个字节 blue 再次填充为 4 个字节 -> 3x 4 个字节 = 12 个字节。

    您可以通过pragma pack等编译器指令更改此行为。

    【讨论】:

    • 它适用于 32 位编译器,但不适用于 64 位编译器。 64 位编译器似乎无法低于 pack(4)
    猜你喜欢
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 2012-11-24
    • 2021-12-16
    相关资源
    最近更新 更多