?!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
注:本文代码试环境为win7 X64 cpu, ~译器ؓgcc4.7.1 ?vs2010
内存寚w是编译器Z便于CPU快速访问而采用的一Ҏ?/span>
我们先从一个例子开始,对下面的c?或者结构体)
class node
{
char c;
int i;
short s;
}no;
sizeof(no)的值是多少呢,如果你的回答?(1+4+2)Q那么你应该认真阅读下面的内宏V可以在~译器上试试Q输出的l果?2Q这是内存寚w的结果?/span>
Z么要q行内存寚w呢?
q_原因(UL原因)Q不是所有的gq_都能讉KL地址上的L数据的;某些gq_只能在某些地址处取某些特定cd的数据,否则抛出g异常?/span>
性能原因Q数据结?其是栈)应该可能地在自然边界上寚w。原因在于,Z讉K未对齐的内存Q处理器需要作两次内存讉KQ而对齐的内存讉K仅需要一ơ访问? 本文地址
~译器一般按照几个字节对齐呢Q本文中两个~译器默认按照类中最大类型长度来寚wQ我么也可以使用语句#pragma pack(i)(i = 1,2,4,8,16)来设|对齐字节数目,vsq可以在目属?配置属?c/c++-代码生成-l构成员寚w讄?/span>
寚w规则如下Q?/span>
如果讄了内存对齐ؓ i 字节Q类中最大成员对齐字节数为jQ那么整体对齐字节n = min(i, j) Q某个成员的寚w字节数定义:如果该成员是c++自带cd如int、char、double{,那么其对齐字节数=该类型在内存中所占的字节敎ͼ如果该成员是自定义类型如某个class或者structQ那个它的对齐字节数 = 该类型内最大的成员寚w字节数《详见实?》)
每个成员寚w规则Q类中第一个数据成员放在offset?的位|;对于其他的数据成员(假设该数据成员对齐字节数为kQ,他们攄的v始位|offset应该?min(k, n) 的整数?/span>
整体寚w规则Q最后整个类的大应该是n的整数?/span>
当设|的寚w字节数大于类中最大成员对齐字节数Ӟq个讄实际上不产生M效果Q实?Q;当设|对齐字节数?Ӟcȝ大小是单的把所有成员大相?/span>
我们通过以下几个实例来分?/span>
实例1Q(没有指定寚w字节Q则n = 最大成员(int iQ的大小4Q?/span>
class node
{
char c; //攑֜位置0Q位|区间[0]
int i; //4 = n, 那么攄起始位置应该?的倍数Q即4Q位|区间ؓ[4~7]
short s; //2 < nQ那么放|v始位|应该是2的倍数Q即8Q位|区间ؓ[8~9]
}
此时成员共占用[0~9]10个字节,q要整体寚wQ大应该是4的倍数Q即12
实例2Q(假设指定寚w字节?Q那么n = min(8,4) = 4Q?/span>
class node
{
int i; //攑֜位置0Q位|区间[0~3]
char c; //1 < n, 那么攄起始位置应该?的倍数Q即4Q位|区间ؓ[4]
short s; //2 < nQ那么放|v始位|应该是2的倍数Q即6Q位|区间ؓ[6~7]
}
成员共占据[0~7]8个字节,刚好?的倍数Q因此大是8
实例3Q(假设指定寚w字节?Q则n = min(2,4) = 2Q?/span>
class node
{
char c; //攑֜位置0Q位|区间[0]
int i; //4 > n, 那么攄起始位置应该?的倍数Q即2Q位|区间ؓ[2~5]
short s; //2 = nQ那么放|v始位|应该是2的倍数Q即6Q位|区间ؓ[6~7]
}
此时成员共占用[0~7]8个字节,刚好?的倍数Q因此大是8
实例4Q(按照默认讄Q?/span>
class temp
{
char c;
int i;
short s1;
};
由实?可知Q默认对齐情况下Qtemp的大是12Qtemp的对齐字节数是:三个成员取最大的Q即?Q?/span>
对于nodeQn = 其三个成员对齐字节数取最大,即等于t的对齐字节数Q也是 4?/span>
class node
{
char c; //攑֜位置0Q位|区间[0]
temp t; //4Qtemp的对齐字节数Q?= n, 那么攄起始位置应该?的倍数Q即4Q位|区间ؓ[4~15]
short s; //2 < nQ那么放|v始位|应该是2的倍数Q即16Q位|区间ؓ[16~17]
}
此时成员共占用[0~17]18个字节,q要整体寚wQ大应该是4的倍数Q因此大是20
实例5Q(默然讄Q?/span>
对于nodeQn = 其三个成员对齐字节数取最大,即等于d的对齐字节数Q也是 8?/span>
class node
{
temp t; //攑֜位置0Q位|区间[0~11]
double d; //8Qtemp的对齐字节数Q?= n, 那么攄起始位置应该?的倍数Q即16Q位|区间ؓ[16~23]
short s; //2 < nQ那么放|v始位|应该是2的倍数Q即24Q位|区间ؓ[24~25]
}
此时成员共占用[0~25]26个字节,q要整体寚wQ大应该是8的倍数Q因此大是32.
cȝ承时的内存对?/span>
考虑如下c?/span>
class A
{
int i;
char c1;
}
class B:public A
{
char c2;
}
class C:public B
{
char c3;
}
sizeof(C)l果是多呢Qgcc和vsl出了不同的l果Q分别是8?6
gcc中:C相当于把所有成员i、c1、c2、c3当作是在一个class内部Q?先承后寚w)
vs中:对于AQ对齐后其大是8Q对于BQc2加上寚w后的A的大是9Q对齐后是12Q对于CQc3加上寚w后的B大小?3Q再寚w是16 (先对齐后l承)