结构怪偏移

时间:2014-02-01 10:16:50

标签: c++ struct bmp

#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);
}

任何人都可以告诉我为什么我的程序输出这个:

2 4
16 2
90 =?= 0

但是应该输出这个:

2 2
14 2
90 =?= 90

我不知道为什么BMP_Header中的fileSize有4个偏移,如果2个字符(BMP_Header中的MN)有2个字节大小

我正在使用MinGW

2 个答案:

答案 0 :(得分:2)

这是因为C和C ++通过在其间添加一个或多个字节来编译pad结构。这样做是为了提高数据访问效率。

例如,在第一种情况下,编译器在双字节MN成员和fileSize之间添加了两个字节,这是int,可能是因为在您的目标体系结构中当其地址可被4整除时,访问int的速度会更快。

注意:您可以使用offsetof(struct BMP_Header, fileSize)而不是执行指针操作来计算struct的相应元素的偏移量。

答案 1 :(得分:0)

许多ABI指定结构应根据其最大成员对齐。在您的情况下,BMP_Header的最大成员大小为4个字节,因此它与4个字节对齐。这意味着需要添加一些填充(因为您只有14个字节的值表示)。在MNfilesize成员之间添加填充,以便所有成员都与4字节边界对齐。

请注意,这完全取决于您定位的计算机,如果您正在编译跨平台,则无法依赖结果。