【问题标题】:Combine and unite the sequence of bytes in union在 union 中组合并联合字节序列
【发布时间】:2022-01-22 15:14:45
【问题描述】:

我正在尝试组合和统一来自 int 和 short 的字节序列

在调试和读取内存时,它的对齐方式如下[FF FF FF FF 00 00 00 00]

因为我使用联合,它不应该看起来像这样[FF FF FF FF FF FF 00 00] 吗?

   union uniteByte{
        
        unsigned int blockOne;
        unsigned short blockTwo;
    };
    
    union uniteByte testing;
    
    testing.blockOne =0xffffffff; //4294967295
    testing.blockTwo = 0xffff; //65535
    

    printf("%zu\n",sizeof(testing)); // size is 4 why? shouldn't it be 6?
    printf("%u\n",testing.blockOne); // 4294967295
    printf("%u\n",testing.blockTwo); // 65535
    printf("%p",&testing); //0x7ffeefbff4e0 [FF FF FF FF 00 00 00 00]
    printf("%p",&testing.blockOne); //0x7ffeefbff4e0 <-- the address is the same as in blockTwo
    printf("%p",&testing.blockTwo); //0x7ffeefbff4e0 <-- the address is the same as in blockOne
    

【问题讨论】:

  • 你得到 UB 是因为 %x 需要一个无符号整数,而不是地址。地址必须用%p 打印。另外unsigned short必须打印%d因为它会被提升为int,除非sizeof(short) == sizeof(int)
  • 读取与您编写的最后一个不同的联合成员是依赖于实现的。
  • @phuclv 好的,请做出改变,谢谢
  • @AdrianMole 该结构的问题在于它使用空字节来对齐整数对齐位置。所以如果我们颠倒 blockOne 和 blockTwo 的位置,它看起来像这样[FF FF 00 00 FF FF FF FF]
  • 你可以使用打包结构得到你想要的。

标签: c memory memory-management byte unions


【解决方案1】:

union 的目的是为每个成员使用重叠内存,因此大小是最大成员的大小,必要时加上填充。

如果你想让成员独立,你必须使用struct。要摆脱成员之间和最后的填充,请使用__attribute__((packed))

请注意,这通常会对性能产生影响。在内存和寄存器之间移动数字的 CPU 操作通常具有对齐要求,这就是结构通常具有填充的原因。打包结构时,必须逐字节移动数据,而不是使用单个指令来获取数字的完整大小。因此,只有在内存效率非常高且您需要这种时空权衡时才应该这样做。

【讨论】:

    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 1970-01-01
    • 2020-08-08
    相关资源
    最近更新 更多