Есть две проблемы с кодом:
Выравнивание
По соображениям производительности компилятор, если не указано иное, будет размещать поля структуры на своих "естественных границах", фактически оставляя неинициализированнымипромежутки между полями размера байта.Добавьте
#pragma pack(1)
перед определениями структуры, и все будет в порядке.Это также легко проверить: просто распечатайте размер структуры без и с прагма-пакетом, и вы увидите разницу.
Распределение
Как уже сказал Пол Р., вы должны выделитьпространство для заголовков, а не просто предоставить указатель на структуры.Тот факт, что fileheadfunc работает, является совпадением, просто не было ничего такого, что могло бы быть разбито, когда данные записывались за пределами выделенного пространства.
Последнее, просто для предотвращения: если вы когда-нибудь захотитечтобы вернуть структуры чтения в вызывающую программу, не просто возвращайте указатель на структуру, выделенную в функции, так как это вызовет проблемы, аналогичные тем, что у вас есть.Выделите их в вызывающей функции и передайте указатель на эту переменную в функции чтения заголовка.
РЕДАКТИРОВАТЬ уточнение относительно последней точки:
НЕ
FILEHEADER * fileheadfunc(FILE *image)
{
FILEHEADER header;
...
return &header; // returns an address on the function stack that will
// disappear once you return
}
DO
int fileheadfunc(FILE *image, FILEHEADER *header)
{
...
}
, который будет вызываться следующим образом
...
FILEHEADER header;
returnvalue = fileheaderfunc(imagefile,&header);
EDIT2: только что заметил, что способ чтения DIB-заголовка неправильный.Есть несколько вариантов этого заголовка, с разными размерами.Поэтому после прочтения заголовка файла сначала необходимо прочитать 4 байта в целое число без знака и на основе прочитанного значения выбрать правильную структуру заголовка DIB для использования (не забудьте, что вы уже прочитали ее первое поле!) Или сообщите пользователю, с которым вы столкнулисьнеподдерживаемый формат файла.