struct Vector {
int x;
int y;
int z;
};
Большинство скажет: sizeof(Vector) == 3 * sizeof(int) . int как правило равен 4 байтам, т.е. данная структура по идее должна занимать 12 байт. Теоретически - это так. Но (!) практически - как выставите опции компилятора.
Данная "фича" называется "Выравнивание" или "Data Structure Alignment". Она выравнивает размер структуры данных до кратного некоторому числу(естесственно степени 2), например 2, 4, 8. Располагает данные в нужном порядке, а между ними размещает "заполнитель" :) пустоту вобщем.
Для чего это нужно? Здесь описано. Вкратце, это оптимизация данных для ускорения доступа. Как всегда, есть некая точка равновесия между размером данных и скоростью доступа к ним. Короче, должно быть использовано с умом и пониманием.
К каким последствиям это может привести? Последствием может быть неправильное чтение/запись структуры, если оно чётко определено стандартом. Это могут быть различные заголовки файлов, данные и т.д. Такое бы уже не прошло:
read(file, &my_struct, sizeof(my_struct));
write(file, &my_struct, sizeof(my_struct));
Для меня эта новость была неожиданной и привела к нескольким часам выяснения, почему заголовок BMP файла читается неправильно. Оказалось, что IDE Borland Turbo C++ по умолчанию выставлял опцию компилятора - выравнивание в 4 байта.
Вообще заголовок BMP файла должен был занимать 14 байт, но sizeof(BMPHeader) упорно возвращал 16! И из-за этого я никак не мог прочитать смещение до самих данных.
Выставить нужно смещение можно либо выставив опции компилятора, либо директивами:
#pragma pack(push) /* push current alignment to stack */p.s.: компилятор borland и IDE Borland TurboC++ используются сугубо по требованию преподавателя.
#pragma pack(1) /* set alignment to 1 byte boundary */
/** твоя структура */
#pragma pack(pop) /* restore original alignment from stack */
Я для себя сделал один вывод:
ОтветитьУдалитьНе пользоваться компилятором от
IDE Borland Turbo C++