结构奇怪的偏移

Structures strange offset

本文关键字:结构      更新时间:2023-10-16
#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 %dn%d %dn%d =?= %dn", 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中的文件尺寸有4个偏移,如果2个字符(MN中的MN)具有2个字节大小

我正在使用mingw

这是因为C和C 编译器 pad 结构通过在之间添加一个或多个字节。这样做是为了效率。

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

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

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

请注意,这完全取决于您要定位的机器,并且如果您要编译跨平台。