C++结构内部数据对齐规则总结
C++结构内部数据对齐规则总结
2007年03月12日 星期一 19:18
有关的要点
1 对齐与编译时选择对齐方式有关系
2 与结构内数据的类型有关系
具体规则.
第一个结构成员后的每个结构成员将存储在成员中类型大小最大的类型的大小或 n 字节边界(其中 n 为 1、2、4、8 或 16)两者中较小的一个边界上。n字节边界是由/Zp[n]设置的。边界内不能容纳下一个数据,则补位,重起一个边界分配下一个数据。
举个例子
编译选项 /Zp1
表示使用1个字节进行对齐
struct{
short a1; // short 2个字节
short a2; //
int a3; // int 4个字节
char a4; // char 1个字节
short a5; //short 2个字节
long a6;// long 4个字节
char a7; // char 1个字节
__int64 a8; // unsigned 4个字节
}h;
编译选项 /Zp1
表示使用1个字节进行对齐
1个字节小于全部成员中类型最大的类型的大小,所以对齐以1个字节为基准
所以实际每个数据分配内存后,下一个数据会紧接着分配,不会有空位来补充。所以最后的输出是24个字节。
编译选项 /Zp2
表示使用2个字节进行对齐
2个字节小于全部成员中类型最大的类型的大小,所以对齐以2个字节为基准
我们看一下,
a1为2个字节,分配2个字节
a2为2个字节,紧跟a1分配2个字节
a3为4个字节,紧跟a2分配4个字节
a4为1个字节,紧跟a3分配1个字节
a5为2个字节,a4后面现在是单数位置,补1个字节才是2个字节的边界,a4后面补1个字节的空位,a5然后分配2个字节
a6为4个字节,紧跟a5分配4个字节
a7为1个字节,紧跟a6分配1个字节
a8为8个字节,a7后面现在是单数位置,补1个字节才是2个字节的边界,a7后面补1个字节的空位,a8然后分配8个字节
所以总共是26个字节
编译选项 /Zp4
表示使用4个字节进行对齐
4个字节小于全部成员中类型最大的类型的大小,所以对齐以4个字节为基准
a1为2个字节,分配2个字节
a2为2个字节,紧跟a1分配2个字节
a3为4个字节,紧跟a2分配4个字节
a4为1个字节,紧跟a3分配1个字节
a5为2个字节,a4后面现在是单数位置,补1个字节才是2个字节的边界,a4后面补1个字节的空位,a5然后分配2个字节
a6为4个字节,紧跟a5分配4个字节
a7为1个字节,紧跟a6分配1个字节
a8为8个字节,a7后面现在是单数位置,补3个字节才是新的4个字节的边界,a7后面补3个字节的空位,a8然后分配8个字节
所以总共是28个字节
编译选项 /Zp8
表示使用8个字节进行对齐
8个字节等于全部成员中类型最大的类型的大小,所以对齐以8个字节为基准
a1为2个字节,分配2个字节
a2为2个字节,紧跟a1分配2个字节
a3为4个字节,紧跟a2分配4个字节
a4为1个字节,紧跟a3分配1个字节
a5为2个字节,a4后面现在是单数位置,补1个字节才是2个字节的边界,a4后面补1个字节的空位,a5然后分配2个字节
a6为4个字节,紧跟a5分配4个字节
a7为1个字节,紧跟a6分配1个字节
a8为8个字节,a7后面现在是单数位置,补7个字节才是新的8个字节的边界,a7后面补7个字节的空位,a8然后分配8个字节
所以总共是32个字节
编译选项 /Zp16
表示使用16个字节进行对齐
16个字节大于全部成员中类型最大的类型的大小,所以对齐以成员中类型最大的类型的大小8个字节为基准
等同于/Zp8
在VC++.net 2005下,缺省是8字节边界对齐
结构的位域于此类似。
需要注意的是,连续的同类型只要大小总和在该类型范围内可以看作是一个类型进行分配。(这里win32下,int和long可以看作同类型,字节数相同)
例如:
struct {
char a1;
int a2;
int a3:1;
int a4: 5;
char a5: 3;
int a6:1;
short a7:1;
__int64 a9;
}tt;
相当于结构中有如下数据类型 char int int char int short __int64 数据进行分配
编译选项 /Zp1
表示使用1个字节进行对齐
1个字节小于全部成员中类型最大的类型的大小,所以对齐以1个字节为基准
所以总共是24个字节
编译选项 /Zp2
所以总共是26个字节
等等
现在总结是这样的,大家看看还有什么补充和不足的地方。
近期评论