按位结构的大小错误

时间:2014-02-23 23:31:56

标签: android c++ iphone struct ios-simulator

我有按位C ++结构:

struct MXBodyStateCompact {
    uint8_t angle : 8;
    uint16_t positionX : 16;
    uint16_t positionY : 16;

    void Set(MXBodyState state);
    void GetState(MXBodyState *state);
};

它在iPhone上完美运行 - 每个实例5个字节。正是我需要的。

但在iOS模拟器和Android上遇到麻烦。每个实例分配6个字节。虽然angle仍然是1个字节长(根据sizeof),但它在内存中需要2个字节:

(gdb) p sizeof(*this)
$4 = 6
(gdb) p sizeof(this->angle)
$5 = 1
(gdb) p sizeof(this->positionX)
$6 = 2
(gdb) p sizeof(this->positionY)
$7 = 2
(gdb) p this
$8 = (struct MXBodyStateCompact *) 0x7ee5d035
(gdb) p &this->angle
$9 = (uint8_t *) 0x7ee5d035 "X"
(gdb) p &this->positionX
$10 = (uint16_t *) 0x7ee5d037
(gdb) p &this->positionY
$11 = (uint16_t *) 0x7ee5d039

如您所见,angle的地址与positionX的地址之间有2个字节。

有没有办法强制编译器/系统尊重struct字段的大小?或者需要找到其他方法如何处理我的二进制文件? (我使用这个结构来处理二进制文件中的数据。)

2 个答案:

答案 0 :(得分:2)

使用__attribute__((packed))告诉gcc或clang不要在此结构的成员之间插入填充。

struct __attribute__((packed)) MXBodyStateCompact {
    uint8_t angle : 8;
    uint16_t positionX : 16;
    uint16_t positionY : 16;

    void Set(MXBodyState state);
    void GetState(MXBodyState *state);
}

此外,: 8: 16似乎没必要。

答案 1 :(得分:0)

检查一下:http://en.wikipedia.org/wiki/Data_structure_alignment

数据对齐意味着将数据放入存储器偏移量等于字大小的某个倍数,这会因CPU处理内存的方式而提高系统性能。为了对齐数据,可能需要在最后一个数据结构的末尾和下一个数据结构的开头之间插入一些无意义的字节,即数据结构填充。