C/C++字节对齐总结

  现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。简单来说就是牺牲空间来增加访问效率。

其准则如下:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

下面来说一说对齐的规则:

例1:

struct test1
{
int ia;   
double da;  

char ca;
};

  sizeof(test1) = 24

让我们看看他们在内存上是如何分布的:

 

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

ia

ia

ia

ia

 

 

 

 

da

da

da

da

da

da

da

da

ca

 

 

 

 

 

 

 

 

 

 

 

double类型的da首地址必须为8的倍数,编译器在ia和da的中间加4个填充字节,结构体的总大小为8的倍数,编译器在末尾填充7个填充字节。

  例2:

struct test2
{
short sa;
short sb;
double da;

};

sizeof(test2) = 16

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

sa

sa

sb

sb

 

 

 

 

da

da

da

da

da

da

da

da

ca

 

 

 

 

short sb的对齐值为2,所以可以在3,4位置上。

 

那我们如何能按自己的意愿指定对齐值呢?

使用 #pragma pack(n),编译器会按n和结构体中最长的成员的长度中较小者为其值。

使用#pragma pack(2)之后 sizeof(test2) = 12,da的首地址为4。

若想在同一文件中使不同结构体按不同值来对齐,还可使用__attribute__ ((__packed__))来为每一个结构体声明。

 

参考资料:百度百科http://baike.baidu.com/link?url=0JTcfOdOwII5V0F99OTbJnGXaDd6CtrEXy-tJHja3fQ7GmEhQ-4rVRdhhmjZtnUDyIGb7xOwEMjLf-i_BjEoI6Q5YzkCLIS0Ga1MZMDfExdP1-coCojy74OP7deoTovA

posted @ 2016-10-17 14:46  爱吃土豆的男孩  阅读(250)  评论(0编辑  收藏  举报