内存对齐的问题主要存在于理解struct和union等复合结构在内存中的分布
为什么要求内存对齐?
对齐原因
程序:
#include <iostream>
using namespace std;
struct Test_A
{
char a;
char b;
int c;
};
struct Test_B
{
char a;
int c;
char b;
};
struct Test_C
{
int c;
char a;
char b;
};
int main()
{
struct Test_A a;
memset(&a, 0, sizeof(a));
struct Test_B b;
memset(&b, 0, sizeof(b));
struct Test_C c;
memset(&c, 0, sizeof(c));
// Print the memory size of the struct
cout<<"a的大小:"<<sizeof(a)<<endl;
cout<<"b的大小:"<<sizeof(b)<<endl;
cout<<"c的大小:"<<sizeof(c)<<endl;
return 0;
}
运行结果:
定义的三个结构体只有 成员定义的顺序不同,就出现了不同的结构体大小,为什么呢?
这就是内存对齐。为什么要有内存对齐呢?该占用多大的内存,那就开辟对应大小的内存就好了,好比上面的结构体,两个char类型和一个int类型,大小应该是6bytes才对啊,怎么又是8bytes,又是12bytes的啊?
对于内存对齐,主要是为了提高程序的性能,数据结构,特别是栈,应该尽可能地在自然边界上对齐。原因在于,为了访问未对其的内存,处理器需要做两次内存访问;然而,对齐的内存访问仅仅需要一次内存访问。
#include <stdio.h>
struct Test
{
char a;
int b;
int c;
char d;
};
int main()
{
struct Test structTest;
printf("&a=%p\n", &structTest.a);
printf("&b=%p\n", &structTest.b);
printf("&c=%p\n", &structTest.c);
printf("&d=%p\n", &structTest.d);
printf("sizeof(Test)=%d\n", sizeof(structTest));
return 0;
}
结构体Test的成员变量b占用字节数为4bytes,所以只能存储在4的整数倍的位置上,由于a只占用1一个字节,而a的地址0018ff38和b的地址0018ff3c之间相差4bytes,这就说明,a其实也占用了4个字节,这样才能保证b的起始地址是4的整数倍。这就是内存对齐。如果没有内存对齐,我们再拿上面的代码作为例子,则可能输出结果如下:
&a=0018ff38
&b=0018ff39
&c=0018ff3d
&d=0018ff41
可以看到,a占用了一个字节,紧接着a之后就是b;之前也说了,内存对齐是操作系统为了快速访问内存而采用的一种策略,简单来说,就是为了防止变量的二次访问。操作系统在访问内存时,每次读取一定的长度(这个长度就是操作系统的默认对齐系数,或者是默认对齐系数的整数倍)。没有了内存对齐,当我们读取变量c时,第一次读取0018ff3c~0018ff3f的内存,第二次读取0018ff40~0018ff43的内存,由于变量c所占用的内存跨越了两片地址区域,为了正确得到变量c的值,就需要读取两次,将两次内存合并进行整合,这样就降低了内存的访问效率
对齐规则
参考:脚本之家:http://www.jb51.net/article/56007.htm
同样写的很棒的有:http://www.cppblog.com/cc/archive/2006/08/01/10765.html
http://blog.csdn.net/hbuxiaofei/article/details/9491953