c语言,内存字节对齐
引用:内存字节对齐
写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧.
/******************************分割线 如果体系结构是不对齐的,A中的成员将会一个挨一个存储,从而sizeof(a)为11。显然对齐更浪费了空间。那么为什么要使用对齐呢? 体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。比如说读写时.............此处省略50万字
***********************************************************/
上面是你随便 google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则:(在没有#pragma pack宏的情况下,务必看完最后一行)
等你看完此3条原则,2分钟已经过去,抓紧时间,实战3分钟:
typedef struct bb { int id; //[0]....[3] double weight; //[8].....[15] 原则1 float height; //[16]..[19],总长要为8的整数倍,补齐[20]...[23] 原则3//注意4字节对其的编译器里面最大基数为4。 }BB; typedef struct aa { char name[2]; //[0],[1] int id; //[4]...[7] 原则1 double score; //[8]....[15] short grade; //[16],[17] BB b; //[24]......[47] 原则2 }AA; int main() { AA a; cout<<sizeof(a)<<" "<<sizeof(BB)<<endl; return 0; }
结果是 48 24 ok,上面的全看明白了,内存对齐基本过关.
再讲讲#pragma pack(). 在代码前加一句#pragma pack(1),你会很高兴的发现,上面的代码输出为 32 16 bb是4+8+4=16,aa是2+4+8+2+16=32; 这不是理想中的没有内存对齐的世界吗.没错,#pragma pack(1),告诉编译器,所有的对齐都按照1的整数倍对齐,换句话说就是没有对齐规则.
明白了不?
那#pragma pack(2)的结果又是多少呢?对不起,5分钟到了,自己去测试吧.
ps:Vc,Vs等编译器默认是#pragma pack(8),所以测试我们的规则会正常;注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐。套用三原则里计算的对齐值是不能大于#pragma pack指定的n值。
源文档 <http://blog.csdn.net/hairetz/article/details/4084088>
测试: // demo.cpp : 定义控制台应用程序的入口点。 // vs2010 #include "stdafx.h" #include "stdlib.h" #include <stdio.h> typedef struct bb { int id; //[0]....[3] double weight; //[8].....[15] 原则1 float height; //[16]..[19],总长要为8的整数倍,补齐[20]...[23] 原则3//注意4字节对其的编译器里面最大基数为4。 }BB; typedef struct aa { char name[2]; //[0],[1] int id; //[4]...[7] 原则1 double score; //[8]....[15] short grade;//[16],[17] BB b; //[24]......[47] 原则2 }AA; typedef struct zz { char name[2]; //[0],[1] int id; //[4]...[7] 原则1 double score; //[8]....[15] short grade;//[16],[17] BB b; //[24]......[47] 原则2 char a; }ZZ; int _tmain(int argc, _TCHAR* argv[]) { AA a; BB b; ZZ z; printf("sizeof(a) = %d, sizeof(BB) = %d\n",sizeof(a),sizeof(BB)); printf("sizeof(z) = %d\n",sizeof(z)); printf("size max = double = %d\n",sizeof(double) ); system("pause"); return 0; } /** sizeof(a) = 48, sizeof(BB) = 24 sizeof(z) = 56 size max = double = 8 请按任意键继续. . . **/
// demo.cpp : 定义控制台应用程序的入口点。 // linux #include <stdio.h> typedef struct bb { int id; //[0]....[3] double weight; //[8].....[15] 原则1 float height; //[16]..[19],总长要为8的整数倍,补齐[20]...[23] 原则3//注意4字节对其的编译器里面最大基数为4。 }BB; typedef struct aa { char name[2]; //[0],[1] int id; //[4]...[7] 原则1 double score; //[8]....[15] short grade;//[16],[17] BB b; //[24]......[47] 原则2 }AA; typedef struct zz { char name[2]; //[0],[1] int id; //[4]...[7] 原则1 double score; //[8]....[15] short grade;//[16],[17] BB b; //[24]......[47] 原则2 char a; }ZZ; int main(int argc, char* argv[]) { AA a; BB b; ZZ z; printf("sizeof(a) = %d, sizeof(BB) = %d\n",sizeof(a),sizeof(BB)); printf("sizeof(z) = %d\n",sizeof(z)); printf("size max = double = %d\n",sizeof(double) ); return 0; } /** root@oucaijun:/work/dcc# gcc *.c; ./a.out sizeof(a) = 36, sizeof(BB) = 16 sizeof(z) = 40 size max = double = 8 **/
|