您的位置:首页 > 其它

自定义类型变量的大小(数据对齐)

2015-06-17 18:08 246 查看
这个其实是老师留的作业,自己就研究了一把,结果发现和老师讲的方法不一样,但是思路还是具体一样的,我觉得还是一个知识点,只要能够说清楚,明白,那是最好的。

一说到这种大小问题,其实就不简简单单的是语言的问题,更重要的是还和编译器,和操作系统都密不可分。

首先说一说在windows下的结构体的大小吧:

首先为了提高效率,提高存储系统的性能,每一个数据所分配的地址与该数据的类型都有密不可分的联系,例如:&y
0x001dfc0c int *
&ch 0x001dfc1b ""
char * &sh 0x001dfc00
short *这是我在vs2008中定义的一些变量,并且取了地址,转化为十进制之后地址分别为 1,965,068 1,965,083 1,965,056 第一个地址可以sizeof(int)整除,同理后两个也是,意思就是说 编译器给一个变量分配的地址一定能被它(变量)所占的字节数(大小)所整除,这就给我们接下来的重点奠定了基础了。


直接来一个代码看看,

struct su{

char ch; //0x0 若这行数据占1B那么int的地址就是0x1,不能被4整除,所以就占4个字节

int y; //0x4

short sh;//0x8若这行占2B 那么下一个结构(不一定为结构变量)的地址应为0x10,不能满足被4整除

};


在vs中大小是12,按照不知道数据对齐的人的理解char应该是一个字节,int是4个,而short是2个,那么总的大小应该是7.

结构体是不同类数据的聚合,就像数组一样,他们占据的是一整块内存,那么好,咱们刚才也说了地址与数据自身类型的关系,那么对于上述的结构体ch占有一个字节,那么 y 能不能紧跟其后呢,显然是不行,因为它要满足 [b]一个变量分配的地址一定能被它(变量)所占的字节数(大小)所整除
的条件,所以很明显,对于一个ch 来说,其实他后面还要在浪费3B的空间才能让y放入,y可以放入之后,看看sh 2B 那么是可以被接着放的,这样的话结果应该是10,可是编译器告诉我们是12,这是为什么呢,原因是每个结构体又有一个最宽数据(名字我给忘了,sorry),也就是说,一个结构体的大小还要能被最宽数据大小整除,在此例中,最宽的应该是int那么整个结构的大小就是10+2(在short后在补上两个字节),这样做的原因是,如果来一个这样结构的数组,那么得能够保证数组元素之间实现无缝聚合。[/b]

[b]struct su{

char ch;//1+7

double dou;//8

int y;//4

int i;//4

int j;//4+4

};

[/b]

产生一个32B变量。但是在linux中,却不这样做,它要满足能被8B以上的数据按4B对齐。

#pragma pack(4)

struct su{

char ch;

double dou;

char y;

int i;

int j;

};

#pragma pack()



在vs中可以用上述方法改变最大数据对齐方式,也就是将超过4B的数据全都按照4B的方法对齐,结果是24。

#pragma pack(4)

struct su{

char ch;//1

char dou;//1

char y;//1+1

int i;//4

int j;//4

};

#pragma pack()



结果为12B。

先写这么多,有时间了将会写一下结构中有其他自定义类型的情况。

可能有不是那么准确的地方,体谅。











内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: