内存对齐应用于三种数据类型中:struct、class、union;
为什么要内存对齐:提高内存访问效率,减少cpu访问内存次数
用sizeof运算符可以得到整个结构体占用内存的大小。
注意:整个结构体占用内存的大小不一定等于全部成员占用内存之和。
内存对齐:#pragma pack(字节数) 如果用1,那么内存之间就没有空隙了
合理使用内存对齐规则,某些节省内存的做法可能毫无意义。
位域:
位域定义与结构体定义相仿,其形式为:
struct 位域结构名{ 位域列表 }
其中位域列表的形式为:
type [member_name] : width;
结构体内存对齐规则:
1、首先看有没有#pragma pack宏定义,有这个宏的情况下结构体的自身宽度是宏定义的数值(但是当成员中占用字节数最大的类型的字节大小比宏定义的数值小的时候,会按照字节数来)#pragma pack 的参数只能是 1、2、4、8、16;
2、在没有#pragma pack声明的情况下,一般遵循三个原则:
(1) 第一个成员的首地址为0;
(2)每个成员的首地址是自身大小的整数倍;
(3) 结构体的总大小,为其成员中所含最大类型的整数倍。
遵循以上规则,做一些练习:
以下都以32位操作系统为例(32位和64位下数据类型有一些区别,例如long在32位系统下占4字节,在64位下占8字节;指针在32下占4字节,在64下占8字节)
struct A{ char a1; char a2; short a3; }
但是如果将a2和a3换位置后,这个结构体所占的内存就会改变:
struct AA{ char a1; short a2; char a3; }
struct B{ char * a1; char arr[7]; short a2; double a3; }
struct stu{ char * a; short b; char arr[20]; } struct A{ int a; long b; stu c; int arr[10]; }
我们看A,最大的类型为long,4字节,所以a从0开始,4个字节,不足4字节,自动补齐,b从4开始,到7结束,然后看c,c中最大是a,4字节,a从下标8开始,到11结束,b从12开始,到13结束,arr从14开始,到33结束,此时stu有26个大小,但是不是4的整数倍,所以内存对齐,arr占28个字节,此时stu到35,int arr占从36开始,占40个字节大小,到75,所以整个结构体A的大小为76。
如果使用#pragma pack的情况下,
#pragma pack(1) 代表内存之间没有空隙
如果使用#pragma pack(2)呢?看下边的示例
#pragma pack(2) struct test{ int *a; char b; short c[20]; }
但是当有了#pragma pack 宏定义后,不一定一定会按照宏定义的数值来进行内存对齐;
当结构体中的最大的数据类型的大小 小于 宏定义的大小时,就会以结构体中最大的数据类型的大小来进行内存对齐
#pragma pack(8) struct test { char a; int b; short c; };
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。