当前位置: 技术问答>linux和unix
struct结构体竟这般无赖!!!!!!!!!!!!!!!!!!!
来源: 互联网 发布时间:2016-12-29
本文导语: 关于结构体遇到了问题哪位帮忙分析下: 就是定义一个BMP格式的结构体用于存储图片的头信息,然后从图片像这个结构体读数据。 结构体如下:typedef struct{ short bfType; //__attribute__((packed)); long bfSize...
关于结构体遇到了问题哪位帮忙分析下:
就是定义一个BMP格式的结构体用于存储图片的头信息,然后从图片像这个结构体读数据。
结构体如下:typedef struct{
short bfType; //__attribute__((packed));
long bfSize; //__attribute__((packed));
short bfReserved1;
short bfReserved2;
long bfOffBits;
long biSize;
long biWidth;
long biHeight;
short biPlanes;
short biBitCount;
long biCompression;
long biSizeImage;
long biXpp;
long biYpp;
long biClrUsed;
long biClrImportant;
}BMPHEAD;
void ShowBMP(char *filename,short x,short y)
{
BMPHEAD bmp_inf;
FILE *fp;
char Tmp,*buf,*buf1,*buf2,c;
int width,height;
int red,green,blue;
long aver_size,size,i,m,j,k;
fp=fopen(filename,"rb");
if(!fp) return;
fseek(fp,2L,0);
fread(&bmp_inf.bfSize,1,52,fp);
.....
}
问题: fseek(fp,2L,0); fread(&bmp_inf.bfSize,1,52,fp);为何像这样从第二个参数开始copy数据就能得到正确的数据?
而 改成这样,fseek(fp,0,0); fread(&bmp_inf.bfType,1,54,fp)从第一开始就得到的数据不正确?
还有就是为何sizeof(结构体)的大小都是4的倍数,而不一定就是实际的大小?这样就求大小和处理时就很不准确了。
就是定义一个BMP格式的结构体用于存储图片的头信息,然后从图片像这个结构体读数据。
结构体如下:typedef struct{
short bfType; //__attribute__((packed));
long bfSize; //__attribute__((packed));
short bfReserved1;
short bfReserved2;
long bfOffBits;
long biSize;
long biWidth;
long biHeight;
short biPlanes;
short biBitCount;
long biCompression;
long biSizeImage;
long biXpp;
long biYpp;
long biClrUsed;
long biClrImportant;
}BMPHEAD;
void ShowBMP(char *filename,short x,short y)
{
BMPHEAD bmp_inf;
FILE *fp;
char Tmp,*buf,*buf1,*buf2,c;
int width,height;
int red,green,blue;
long aver_size,size,i,m,j,k;
fp=fopen(filename,"rb");
if(!fp) return;
fseek(fp,2L,0);
fread(&bmp_inf.bfSize,1,52,fp);
.....
}
问题: fseek(fp,2L,0); fread(&bmp_inf.bfSize,1,52,fp);为何像这样从第二个参数开始copy数据就能得到正确的数据?
而 改成这样,fseek(fp,0,0); fread(&bmp_inf.bfType,1,54,fp)从第一开始就得到的数据不正确?
还有就是为何sizeof(结构体)的大小都是4的倍数,而不一定就是实际的大小?这样就求大小和处理时就很不准确了。
|
结构体出于地址对齐的原因,会进行调整。结构体的大小,是其成员变量都进行空间地址对齐后的占用内存的大小。而由于32系统架构的内存空间地址对齐的要求一般为4字节对齐,因此sizeof的大小都是4的倍数。
请参考我的博客:
http://blog.csdn.net/iterzebra/article/details/6232079
http://blog.csdn.net/iterzebra/article/details/6232039
请参考我的博客:
http://blog.csdn.net/iterzebra/article/details/6232079
http://blog.csdn.net/iterzebra/article/details/6232039
|
结构体会以最长的对齐,比如你的结构体如下,最大的是long类型,在你机器上是4字节,所以实际占用如下
bfType 0 1 [2 3]
bfSize 5 6 7 8
bfReserved1 9 10
bfReserved2 11 12
bfOffBits 13 14 15 16
虽然bfType实际只用了2个字节,但为了与最大的long对齐,扩展为了4字节。后面bfReserved1, bfReserved2虽然也是2字节,但它们正好填满一个4字节,所以不用扩展。简单来说,结构体以最大类型所占字节数对齐
如果long是8字节,则
bfType 0 1 [2 3 4 5 6 7]
bfSize 8 9 10 11 12 13 14 15
bfReserved1 16 17
bfReserved2 18 19 [20 21 22 23]
bfOffBits 24 25 26 27 28 29 30 31
struct{
short bfType; //__attribute__((packed));
long bfSize; //__attribute__((packed));
short bfReserved1;
short bfReserved2;
long bfOffBits;4
....
}
bfType 0 1 [2 3]
bfSize 5 6 7 8
bfReserved1 9 10
bfReserved2 11 12
bfOffBits 13 14 15 16
虽然bfType实际只用了2个字节,但为了与最大的long对齐,扩展为了4字节。后面bfReserved1, bfReserved2虽然也是2字节,但它们正好填满一个4字节,所以不用扩展。简单来说,结构体以最大类型所占字节数对齐
如果long是8字节,则
bfType 0 1 [2 3 4 5 6 7]
bfSize 8 9 10 11 12 13 14 15
bfReserved1 16 17
bfReserved2 18 19 [20 21 22 23]
bfOffBits 24 25 26 27 28 29 30 31
struct{
short bfType; //__attribute__((packed));
long bfSize; //__attribute__((packed));
short bfReserved1;
short bfReserved2;
long bfOffBits;4
....
}
|
可以在定义结构体之前添加
#pragma pack(1)
指定结构体不对齐.
#pragma pack(1)
指定结构体不对齐.
|
++