Здравствуйте, Saydex, Вы писали:
S>Вот такой код:
S>S>typedef float Vector[3];
S>typedef float Texel[2];
S>typedef float Matrix[4][4];
S>typedef int Bool;
S>typedef unsigned char Byte;
S>typedef unsigned short int Word;
S>typedef unsigned long Dword;
S>typedef float Float;
S>typedef struct _BoxMap {
S> char front[64];
S> char back[64];
S> char left[64];
S> char right[64];
S> char top[64];
S> char bottom[64];
S>}BoxMap;
S>typedef struct _MapData {
S> Word maptype;
S> Vector pos;
S> Matrix matrix;
S> Float scale;
S> Float tile[2];
S> Float planar_size[2];
S> Float cylinder_height;
S>}MapData;
S>typedef struct _Mesh3 {
S> Matrix matrix;
S> Dword points;
S> Dword flags;
S> Dword texels;
S> Dword faces;
S> BoxMap box_map;
S> MapData map_data;
S>}Mesh3;
S>typedef struct _Mesh4 {
S> Byte color;
S> Matrix matrix;
S> Dword points;
S> Dword flags;
S> Dword texels;
S> Dword faces;
S> BoxMap box_map;
S> MapData map_data;
S>}Mesh4;
S>DWORD sm3 = sizeof(Mesh3);
S>DWORD sm4 = sizeof(Mesh4);
S>
S>Так вот sm3 = 568, а sm4 = 572. Но как это получается? Ведь sizeof(Byte) = 1 !
S>У меня стоит Visual C++ 6.0. Что мне делать? Именно из-за этого я не могу сделать так:
S>WriteFile(hFile,&mesh4,sizeof(Mesh4),&dw,0). Ведь оно запишется неправильно!
Как быть?
Придётся вам познакомиться с термином "выравнивание". Дело в том, что размер той или иной структуры не всегда равен размеру её членов. Существуют правила, в соответствии с которыми члены структур должны выравниваться по границе блоков определённого размера. Это необходимо для ускорения доступа к отдельным членам структур (оптимизации) или для достижения соответствия требованиям к памяти в той или иной реализации. Как было сказано выше, члены структур должны быть выравнены по определённой (числом байт!) границе, размеры которой можно регулировать при помощи директивы #pragma pack([push | pop], [size_of_bytes n]).
Я слегка модифицировал ваш код для выравнивания по границе 8 байт (здесь показана лишь та часть кода, которая была подвержена модификации):
#pragma pack(push, 8)
typedef struct _MapData {
Matrix matrix;
Vector pos;
unsigned int : 4;
Float tile[2];
Float planar_size[2];
Float scale;
Float cylinder_height;
unsigned int : 7;
Word maptype;
}MapData;
typedef struct _Mesh3 {
BoxMap box_map;
MapData map_data;
Matrix matrix;
Dword points;
Dword flags;
Dword texels;
Dword faces;
}Mesh3;
typedef struct _Mesh4 {
BoxMap box_map;
MapData map_data;
Matrix matrix;
Dword points;
Dword flags;
Dword texels;
Dword faces;
unsigned int : 7;
Byte color;
}Mesh4;
#pragma pack(pop)
DWORD sm3 = sizeof(Mesh3);
DWORD sm4 = sizeof(Mesh4);
А вот результаты расчётов:
BoxMap — 64*6 = 384
MapData — 64+12+4+8+8+4+4+7+1 = 112 (кратное 8)
Mesh3 — 384+112+64+4+4+4+4 = 576
Mesh4 — 384+112+64+4+4+4+4+7+1 = 584
Битовые поля (bit fields) помогают выравнять члены структур по границам байт.