C++中内存对齐技能实例解说ITeye - 娱乐之横扫全球

C++中内存对齐技能实例解说ITeye

2019-01-10 17:34:39 | 作者: 觅云 | 标签: 对齐,内存,实例 | 浏览: 683



C++ 内存对齐

注:本文代码测验环境为win7 X64 cpu, 编译器为gcc4.7.1 和 vs2010

内存对齐是编译器为了便于CPU快速拜访而选用的一项技能

咱们先从一个比如开端,对下面的类(或许结构体)



class node

{

  char c;


  int i;


  short s;

}no;

sizeof(no)的值是多少呢,假如你的答复是7(1+4+2),那么你应该仔细阅览下面的内容。能够在编译器上试试,输出的成果是12,这便是内存对齐的成果。

为什么要进行内存对齐呢?

渠道原因(移植原因):不是一切的硬件渠道都能拜访恣意地址上的恣意数据的;某些硬件渠道只能在某些地址处取某些特定类型的数据,不然抛出硬件反常。 功能原因:数据结构(尤其是栈)应该尽可能地在天然鸿沟上对齐。原因在于,为了拜访未对齐的内存,处理器需求作两次内存拜访;而对齐的内存拜访仅需求一次拜访。

编译器一般依照几个字节对齐呢?本文中两个编译器默许依照类中最大类型长度来对齐,我么也能够运用句子#pragma pack(i)(i = 1,2,4,8,16)来设置对齐字节数目,vs还能够在项目特点-装备特点-c/c++-代码生成-结构成员对齐设置。

对齐规矩

假如设置了内存对齐为 i 字节,类中最大成员对齐字节数为j,那么全体对齐字节n = min(i, j) (某个成员的对齐字节数界说:假如该成员是c++自带类型如int、char、double等,那么其对齐字节数=该类型在内存中所占的字节数;假如该成员是自界说类型如某个class或许struct,那个它的对齐字节数 = 该类型内最大的成员对齐字节数《详见实例4》) 每个成员对齐规矩:类中第一个数据成员放在offset为0的方位;关于其他的数据成员(假定该数据成员对齐字节数为k),他们放置的开始方位offset应该是 min(k, n) 的整数倍 全体对齐规矩:最终整个类的巨细应该是n的整数倍 当设置的对齐字节数大于类中最大成员对齐字节数时,这个设置实际上不发生任何作用(实例2);当设置对齐字节数为1时,类的巨细便是简略的把一切成员巨细相加

实例剖析

咱们经过以下几个实例来剖析

实例1:(没有指定对齐字节,则n = 最大成员(int i)的巨细4)



class node

{

  char c;  //放在方位0,方位区间[0]


  int i;  //4 = n, 那么放置开始方位应该是4的倍数,即4,方位区间为[4~7]


  short s; //2 n,那么放置开始方位应该是2的倍数,即8,方位区间为[8~9]

}no;

此刻成员共占用[0~9]10个字节,还要全体对齐,巨细应该是4的倍数,即12

实例2:(假定指定对齐字节为8,那么n = min(8,4) = 4)



class node

{

  int i; //放在方位0,方位区间[0~3]


  char c; //1 n, 那么放置开始方位应该是1的倍数,即4,方位区间为[4]


  sh http://www.cppentry.com  编程开发 程序员入门ort s; //2 n,那么放置开始方位应该是2的倍数,即6,方位区间为[6~7]

}no;

成员共占有[0~7]8个字节,刚好是4的倍数,因而巨细是8

实例3:(假定指定对齐字节是2,则n = min(2,4) = 2)



class node

{

  char c; //放在方位0,方位区间[0]


  int i; //4 n, 那么放置开始方位应该是2的倍数,即2,方位区间为[2~5]


  short s; //2 = n,那么放置开始方位应该是2的倍数,即6,方位区间为[6~7]

}no;

此刻成员共占用[0~7]8个字节,刚好是4的倍数,因而巨细是8

实例4:(依照默许设置)



class temp

{

  char c;

  int i;

  short s1;

};

由实例1可知,默许对齐情况下,temp的巨细是12,temp的对齐字节数是:三个成员取最大的,即为4;

关于node,n = 其三个成员对齐字节数取最大,即等于t的对齐字节数,也便是 4。



class node

{

  char c; //放在方位0,方位区间[0]


  temp t; //4(temp的对齐字节数) = n, 那么放置开始方位应该是4的倍数,即4,方位区间为[4~15]


  short s; //2 n,那么放置开始方位应该是2的倍数,即16,方位区间为[16~17]

}no;

此刻成员共占用[0~17]18个字节,还要全体对齐,巨细应该是4的倍数,因而巨细是20

实例5:(默然设置)

关于node,n = 其三个成员对齐字节数取最大,即等于d的对齐字节数,也便是 8。



class node

{

  temp t; //放在方位0,方位区间[0~11]


  double d; //8(temp的对齐字节数) = n, 那么放置开始方位应该是8的倍数,即16,方位区间为[16~23]


  short s; //2 n,那么放置开始方位应该是2的倍数,即24,方位区间为[24~25]

}no;

此刻成员共占用[0~25]26个字节,还要全体对齐,巨细应该是8的倍数,因而巨细是32.

类承继时的内存对齐



class A

{

  int i;

  char c1;

}


class B:public A

{

  char c2;

}


class C:public B

{

  char c3;

}

sizeof(C)成果是多少呢,gcc和vs给出了不同的成果,分别是8、16

gcc中:C相当于把一切成员i、c1、c2、c3当作是在一个class内部,(先承继后对齐)

vs中:关于A,对齐后其巨细是8;关于B,c2加上对齐后的A的巨细是9,对齐后便是12;关于C,c3加上对齐后的B巨细是13,再对齐便是16 (先对齐后承继)

关于c++目标承继后的内存布局,更具体的剖析能够《深度探究参阅c++目标模型》第三章

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表娱乐之横扫全球立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1

    java元数据(metadata)ITeye

    数据,注解,一个
  • 2

    java awt Graphics 绘图ITeye

    字符串,二维码,图片
  • 3

    slf4jITeye

    日志,运用,一个
  • 4
  • 5

    spring+mybatis装备ITeye

    装备,一下,需求
  • 6

    文件的读写和操作ITeye

    文件,字节,输出
  • 7

    ubuntu下python办理ITeye

    能够,咱们,经过
  • 8

    第03章 惯例选择器 (2)ITeye

    主页,选择器,运用
  • 9

    zookeeper原理(转)ITeye

    节点,集群,一个
  • 10