Неправильный размер побитовой структуры

0

У меня побитовая структура 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 Simulator и 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
iphone
ios-simulator

2 ответа

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 кажутся ненужными.

  • 0
    Да,: :8 и :16 не нужны, если используется __attribute__((packed)) . Но ранее :8 и :16 производили тот же эффект, что и этот атрибут, при компиляции для iPhone.
0

проверьте это: http://en.wikipedia.org/wiki/Data_structure_alignment

Выравнивание данных означает перенос данных со смещением памяти, равным нескольким кратным размеру слова, что увеличивает производительность системы из-за того, как процессор обрабатывает память. Чтобы выровнять данные, может потребоваться вставить некоторые бессмысленные байты между концом последней структуры данных и началом следующего, что является заполнением структуры данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню