浅谈 内存对齐
2013-05-02 21:09
183 查看
每一个class objet 必须有足够大小以容纳它所有的nonstatc data members。有时候其值可能令你吃惊(正如那位法国来信者),因为它可能比你想象的还大,原因是:
1.由编译器自动加上的额外data members,用以支持某些语言特性(主要是各种virtual 特性)
2.因为alignment(内存对齐)的需要
为什么要内存对齐呢?
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
首先来看一个例子
#include <iostream>
using namespace std;
class A1
{
short a;
char c;
};
void main()
{
cout<<sizeof(A1)<<endl;
}
结果是4,
原因是当结构体或者类内部的最大的元素的长度小于处理器的位数时候,便以结构体内长度最长的那个也元素为对齐单位,这里最长的是short,两个字节,所以第二个char其实也想当于占了两个字节,这样一来就占了四个字节
当然我们也可以通过#pragma pack(n) 来修改对齐系数,这里的n是1,2,4,8等
如果在上例中添加上
#pragma pack(1)
那么结果就成了3
再看下面的这个例子
#include <iostream>
using namespace std;
class A1
{
short a;
int b;
char c;
};
void main()
{
cout<<sizeof(A1)<<endl;
}
根据我们刚才学到的内存对齐原则,很明显结果是12
但是我们在开始加上这一句呢
#pragma pack(8)
结果会不会变成16呢,答案是否定的,因为当pack里面的n值大于结构体内所有元素的长度时候,prama pack(n)就不起作用了
和内存对齐类似的是数据对齐
所谓数据对齐,是指数据所在的位置必须是该数据长度的整数倍,DWORD数据的内存起始地址能被4整除,WORD数据能被2整除 x86 CPU能直接访问一个对齐的数据,如果一个数据没有对齐,会在内部进行一系列的调整
void main()
{
int a;
short d;
int c;
cout<<&a<<endl;
cout<<&d<<endl;
cout<<&c<<endl;
}
看输出结果
1.由编译器自动加上的额外data members,用以支持某些语言特性(主要是各种virtual 特性)
2.因为alignment(内存对齐)的需要
为什么要内存对齐呢?
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
首先来看一个例子
#include <iostream>
using namespace std;
class A1
{
short a;
char c;
};
void main()
{
cout<<sizeof(A1)<<endl;
}
结果是4,
原因是当结构体或者类内部的最大的元素的长度小于处理器的位数时候,便以结构体内长度最长的那个也元素为对齐单位,这里最长的是short,两个字节,所以第二个char其实也想当于占了两个字节,这样一来就占了四个字节
当然我们也可以通过#pragma pack(n) 来修改对齐系数,这里的n是1,2,4,8等
如果在上例中添加上
#pragma pack(1)
那么结果就成了3
再看下面的这个例子
#include <iostream>
using namespace std;
class A1
{
short a;
int b;
char c;
};
void main()
{
cout<<sizeof(A1)<<endl;
}
根据我们刚才学到的内存对齐原则,很明显结果是12
但是我们在开始加上这一句呢
#pragma pack(8)
结果会不会变成16呢,答案是否定的,因为当pack里面的n值大于结构体内所有元素的长度时候,prama pack(n)就不起作用了
和内存对齐类似的是数据对齐
所谓数据对齐,是指数据所在的位置必须是该数据长度的整数倍,DWORD数据的内存起始地址能被4整除,WORD数据能被2整除 x86 CPU能直接访问一个对齐的数据,如果一个数据没有对齐,会在内部进行一系列的调整
void main()
{
int a;
short d;
int c;
cout<<&a<<endl;
cout<<&d<<endl;
cout<<&c<<endl;
}
看输出结果