Search code examples
c++structbmp

Structures strange offset


#include <cstdio>

struct BMP_Header
{
    unsigned char MN[2];
    unsigned int fileSize;
    char unused[4];
    unsigned int bitmapOffset;
};

struct DIB_Header
{
    unsigned int headerSize;
    unsigned int width;
    unsigned int height;
    unsigned short planes;
    unsigned short bits;
    unsigned int compresion;
    unsigned int rawDataSize;
    unsigned int hResolution;
    unsigned int vResolution;
    unsigned int palleteColors;
    unsigned int importantColors;
};

int main() {
    BMP_Header header1;
    DIB_Header header2;
    FILE *f = fopen("1.bmp", "rb");
    fread(&header1, 1, sizeof(BMP_Header), f);
    fread(&header2, 1, sizeof(DIB_Header), f);
    fclose(f);
    char *ptr = ((char*)&header1) + sizeof(unsigned short);
    printf("%d %d\n%d %d\n%d =?= %d\n", ptr - (char*)&header1, (char*)&(header1.fileSize) - (char*)&header1, sizeof(BMP_Header), sizeof(unsigned short), *(int*)ptr, header1.fileSize);
}

Can anyone tell me why my program outputs this:

2 4
16 2
90 =?= 0

But should output this:

2 2
14 2
90 =?= 90

I dont know why fileSize in BMP_Header have 4 offset if 2 chars(MN in BMP_Header) have 2 bytes size

I'm using MinGW


Solution

  • This is because C and C++ compilers pad structures by adding one or more bytes in between. This is done for efficiency of data access.

    For example, in the first case the compiler added two bytes between the two-byte MN member and the fileSize, which is an int, presumably because in your target architecture it is faster to access an int when its address is divisible by 4.

    Note: you can use offsetof(struct BMP_Header, fileSize) instead of doing the pointer manipulation to compute the offset of the corresponding element of the struct.