2011-12-16 3 views
3

Можно создать дубликат:
How do I find the size of a struct?
Struct varies in memory size?C размеры Struct несогласованности

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

Он дает разные размеры, чем ожидалось, 8 байт.

struct HttpPacket { 
    unsigned char x1; 
    union { 
     struct { 
      unsigned char len; 
      unsigned short host; 
      unsigned char content[4]; 
     } packet; 
     unsigned char bytes[7]; 
     unsigned long num; 
    } 

И После дает разный размер, даже если что я извлекая поле от союза

struct HttpPacket { 
      unsigned char x1; 
      union { 
      struct { 
       unsigned char len; 
       unsigned short host; 
       unsigned char content[4]; 
      } packet; 
      unsigned long num; 
     } 

Кроме того, более яркий пример

struct { 
       unsigned char len; 
       unsigned short host; 
       unsigned char content[4]; 
      } packet; 

И это дает размер 8, вместо 7. И я добавляю еще одно поле, оно по-прежнему дает одинаковый размер

struct { 
       unsigned char EXTRAADDEDFIELD; 
       unsigned char len; 
       unsigned short host; 
       unsigned char content[4]; 
      } packet; 

Может кто-то пожалуйста, помогите на решение этой проблемы?

UPDATE: Мне нужен формат для хранения во время передачи пакета, поэтому я хочу, чтобы пропустить эти

Прокладки
+0

Мне нужен формат для хранения при передаче пакета. Поэтому я хочу пропустить эти paddings – coder000001

+0

Нужно это на компиляторе XCode 4 LLVM – coder000001

+0

Но мне нужно решение для нового компилятора LXVM XCode 4. – coder000001

ответ

7

когда-нибудь слышали о alignment and padding?

В принципе, для обеспечения быстрого доступа определенные типы должны быть на определенных границах адресов памяти.
Это называется выравнивание.

Для этого компилятору разрешено вставлять байты в структуру данных для достижения этого выравнивания.
Это называется дополнением.

10

C не дает гарантий на размер struct. Компилятору разрешено выравнивать участников, но он хочет. Обычно, как и в этом случае, он будет выравнивать по размеру, так как это наиболее быстро на большинстве машин.

+1

Некоторые компиляции поддерживают прагмы для отключения заполнения. Это чаще всего встречается в встроенной разработке, но я не знаю, ограничено ли это этим. – Lou

+1

+1 для первого вежливого ответа. – Lou

+0

Дополнительная информация: http://en.wikipedia.org/wiki/Sizeof#Structure_padding – Jon

2

По умолчанию поля структуры выровнены по естественным границам. Например, 4-байтовое поле будет начинаться с 4-байтовой границы. Компилятор вставляет байты pad для этого. Вы можете избежать заполнения с помощью #pragma pack (0) или других аналогичных директив компилятора

+0

Как это сделать на компиляторе LLVM XCode 4 – coder000001

0

Если у вас есть компилятор C99 и вы можете использовать «новые» типы фиксированной ширины: сделайте массив из uint8_t и выполните разделение в членов.

uint8_t data[8]; 

x1 = data[0]; 
len = data[1]; 
host = data[2] * 256 + data[3]; /* big endian */ 
content[0] = data[4]; 
content[1] = data[5]; 
content[2] = data[6]; 
content[3] = data[7]; 

/* ... */ 

Вы можете следовать той же процедуре, описанной в C89, если вы можете рассчитывать на CHAR_BIT быть 8.

Смежные вопросы