struct/class/union内存对齐原则有四个:

1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),基本类型不包括struct/class/uinon。

2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)。

3).收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的"最宽基本类型成员"的整数倍.不足的要补齐.(基本类型不包括struct/class/uinon)。

4).sizeof(union),以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址。

实例解释:下面以class为代表

No.1

class Data
{char c;int a;
};cout << sizeof(Data) << endl;

No.2

class Data
{char c;double a;
};cout << sizeof(Data) << endl;

显然程序No.1 输出的结果为 8    No.2 输出的结果为 16 .

No.1最大的数据成员是4bytes,1+4=5,补齐为4的倍数,也就是8。而No.2为8bytes,1+8=9,补齐为8的倍数,也就是16。

No.3

class Data
{char c;int a;char d;
};cout << sizeof(Data) << endl;

No.4

class Data
{char c;char d;int a;
};cout << sizeof(Data) << endl;

No.3运行结果为 12  No.4运行结果为 8

class中的数据成员放入内存的时候,内存拿出一个内存块来,数据成员们排队一个一个往里放,遇到太大的,不是把自己劈成两半,能放多少放多少,而是等下一个内存块过来。这样的话,就可以理解为什么No.3,No.4两端的代码输出结果不一样了,因为左边是1+(3)+4+1+(3)=12,而右边是1+1+(2)+4=8。括号中为补齐的bytes。

No.5

class BigData
{char array[33];
};class Data
{BigData bd;int integer;double d;
};cout << sizeof(BigData) << "   " << sizeof(Data) << endl;

No.6

class BigData
{char array[33];
};class Data
{BigData bd;double d;
};cout << sizeof(BigData) << "   " << sizeof(Data) << endl;

No.5和No.6运行结果均为: 48

在默认条件下,内存对齐是以class中最大的那个基本类型为基准的,如果class中有自定义类型,则递归的取其中最大的基本类型来参与比较。在No.5和No.6中内存块一个接一个的过来接走数据成员,一直到第5块的时候,BigData里只剩1个char了,将它放入内存块中,内存块还剩7个bytes,接下来是个int(4bytes),能够放下,所以也进入第5个内存块,这时候内存块还剩3bytes,而接下来是个double(8bytes),放不下,所以要等下一个内存快到来。因此,No.5的Data的size=33+4+(3)+8=48,同理No.6应该是33+(7)+8=48。

顺便提一下Union: 共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。

内存对齐的主要作用是:

1、  平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2、  性能原因:经过内存对齐后,CPU的内存访问速度大大提升。具体原因稍后解释。

图一:

这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。

图二:

CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory access granularity(粒度) 本人把它翻译为“内存读取粒度” 。

假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:

1、数据从0字节开始

2、数据从1字节开始

再次假设内存读取粒度为4。

图三:

当该数据是从0字节开始时,很CPU只需读取内存一次即可把这4字节的数据完全读取到寄存器中。

当该数据是从1字节开始时,问题变的有些复杂,此时该int型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。

图四:

此时CPU先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。对一个内存未对齐的数据进行了这么多额外的操作,大大降低了CPU性能。

这还属于乐观情况了,上文提到内存对齐的作用之一为平台的移植原因,因为以上操作只有有部分CPU肯干,其他一部分CPU遇到未对齐边界就直接罢工了。

C/C++ 内存对齐原则及作用相关推荐

  1. C++ 中内存对齐原理及作用

    struct/class/union内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储 ...

  2. 32位操作系统和64位操作系统每种类型占用的字节数、内存对齐原则

    32位操作系统: 1:整形 int 4字节 long int 4字节 short 2字节 unsigned int 4字节 unsigned long int 4字节 unsigned short 2 ...

  3. 内存对齐的规则以及作用

    内存对齐能够用一句话来概括: "数据项仅仅能存储在地址是数据项大小的整数倍的内存位置上" 比如int类型占用4个字节.地址仅仅能在0,4.8等位置上. 由一个程序引入话题: //环 ...

  4. 内存对齐的规则以及作用 verygood!的一篇文章!

    原文转自:http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html 首先由一个程序引入话题: //环境:vc6 + windows  ...

  5. 内存对齐小结(关于计算结构体大小和内存对齐)

    文章目录 1.#pragma pack(push,1)与#pragma pack(1)的区别,及工程使用举例 1)方式一 #pragma pack (n) 2)方式二 #pragma pack(pus ...

  6. iOS之深入解析内存对齐的底层原理

    CPU 存取原理 一."存"示例 CPU 并不是以字节为单位存取数据的.CPU 把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此 CPU 在读取内存时是一块一块 ...

  7. C++ 内存对齐 及 引用是否真的节省内存的一点思考

    文章目录 1. 内存对齐 2. 递归中的内存对齐 3. C++引用的本质 4. 致谢 1. 内存对齐 通过以下语句,获取变量的占用内存打下: cout << "size of i ...

  8. c语言编程中如何对其,C语言内存对齐详解(3)

    在minix的stdarg.h文件中,定义了如下一个宏: /* Amount of space required in an argument list for an arg of type TYPE ...

  9. 内存对齐是什么?为什么要内存对齐?

    原文: http://blog.csdn.net/liupeng900605/article/details/7530010 首先由一个程序引入话题:  1 //环境:vc6 + windows sp ...

  10. 内存对齐的原理,作用,例子以及一些规划(中英文说明,适用sizeof结构体) ...

    目录   题记  一  内存读取粒度   Memory access granularity   从内存的角度解释内存对齐的原理   队列原理 Alignment fundamentals   Laz ...

最新文章

  1. JMeter的安装和使用
  2. C#拾遗系列(4):索引器
  3. 在Linux系统下生产者消费者,生产者-消费者问题实现 (linux下C语言)
  4. PHP 数据库 ODBC
  5. cdn节点人少延迟高_如何正确配置CDN高速缓存,避免越用越慢的尴尬
  6. linux抹掉所有分区,找到了linux分区顺序错乱修复方法
  7. Sublime个性化配置
  8. SI和DI寄存器(0703)
  9. python json dumps 中文_Python下调用json.dumps中文显示问题解决办法
  10. php 监听模式,总结Laravel事件系统用法(监听事件,观察者模式)
  11. shell 逐行读取文件
  12. RIPv1配置(Enabling Rip)
  13. zend studio12配置php,Zend Studio 12.0调试php代码
  14. 润乾报表-单元格函数
  15. 从苏宁电器到卡巴斯基第36篇:我与卡巴斯基的邂逅(上)
  16. Kubernetes(k8s) YAML文件详解
  17. 开机内存占用过高解决方案
  18. uva 12325 宝箱
  19. Python3快速入门教程-zyiz.net
  20. 新手做网站优化要思考三个本质问题!

热门文章

  1. 工作中个人注册的媒体账号离职要归公司所有?
  2. 发现一款好用的 java web报表工具
  3. java 对象转xml 工具类_工具类 Java对象和XML之间的相互转换-搜云库
  4. 平面设计师okr_设计团队如何推进OKR,实现设计赋能?
  5. 计算机中取消打印任务,取消打印任务的具体方法步骤
  6. 去阿诗玛的故乡 云南昆明自助攻略
  7. 计算机sci二区期刊,图像处理的sci二区期刊有哪些
  8. Android 自定义表格(第一行及第一列固定,其他列可滑动)
  9. js 获得较浅的颜色_了解较少的颜色功能
  10. 【双轨】加权分红+三级分销+见点奖+级差源码系统 演示网站介绍