C++内存对齐总结

来源:互联网 发布:离散数学 知乎 编辑:程序博客网 时间:2024/06/04 19:43

    首先说说为什么要对齐。为了提高效率,计算机从内存中取数据是按照一个固定长度的。以32位机为例,它每次取32个位,也就是4个字节(每字节8个位,计算机基础知识,别说不知道)。字节对齐有什么好处?以int型数据为例,如果它在内存中存放的位置按4字节对齐,也就是说1个int的数据全部落在计算机一次取数的区间内,那么只需要取一次就可以了。如果不对齐,很不巧,这个int数据刚好跨越了取数的边界,这样就需要取两次才能把这个int的数据全部取到,这样效率也就降低了。

内存对齐的基本原则:

1.结构体内成员按自身按自身长度自对齐。

自身长度,如char=1,short=2,int=4,double=8,。所谓自对齐,指的是该成员的起始位置的内存地址必须是它自身长度的整数倍。如int只能以0,4,8这类的地址开始

2.结构体的总大小为结构体的有效对齐值的整数倍

结构体的有效对齐值的确定:

1)当未明确指定时,以结构体中最长的成员的长度为其有效值

2)当用#pragma pack(n)指定时,以n和结构体中最长的成员的长度中较小者为其值。

3)当用__attribute__ ((__packed__))指定长度时,强制按照此值为结构体的有效对齐值

4)不管pragma pack和__attribute__如何指定,结构体内部成员的自对齐仍然按照其自身的对齐值。

例子

1、

struct AA{

    char a;

    int b;

    char c; 

}aa

sizeof(aa)=12

原因:char占一个字节,可以在任何地址开始,int占4个字节,只能从0、4、8...开始,对于本题,只能从4开始,尽管1-3都空着,最后的char占一个字节,所以总长度是9,由第二条原则,总长度必须是4的整数倍,所以只能是12.

2、

struct AA{

    char a;

char c; 

    int b;    

}aa

sizeof(aa)=8

原因:char占一个字节,从地址1开始,紧跟着的char也占一个字节,从地址2开始,int占4字节,共6字节,有效对齐长度是sizeof(int)=4,所以是8.


3、

#pragma pack(2)

struct AA{

    char a;

    int b;

    char c; 

}aa

sizeof(aa)=10(注:在vs2010下运行结果是8,应该是不同编译器对于内存的分布进行优化,实际做题还是以10位结果

原因:同例1,总长度是9字节,因为结构体的有效对齐长度在pack指定的2和int的4中取较小的值2,所以总长度是10;如果#pragma pack(8),则有效对齐长度为4,总长度为12.

4、

struct AA{

    char a;

    int b;

    char c; 

}__attribute__((__8__))aa

sizeof(aa)=16

原因:同例1,总长度是9字节,因为结构体的有效对齐长度在强制指定的8字节,所以结果为16;若果指定为2,则结果为10.

5、在一个16位的机器上,一下结构由于数据边界对齐浪费了多少空间?

struct{     char a;     int b;     char c;}

解:在16位的机器上,int占2个字节,所以整个结构体总长度是4,但由于字节对齐,实际占用长度是6,也就是浪费两个字节。

参考:http://blog.csdn.net/andy572633/article/details/7213465

0 0
原创粉丝点击