内存对齐

为啥要对齐:

  1、平台问题:并非所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处获取某些特定类型的数据,否则抛出异常

   2、硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升

对齐规则:

  1、结构体中第一个成员与结构体偏移量为0

  2、其他成员偏移为该成员大小整数倍

  3、结构体总大小为对齐数的整数倍(对齐数为编译器预设值与最大数据类型大小的较小值)

  4、virtual函数可以看作是最大类型的倍数,不管它的位置在哪。若类中有结构体,则最大类型要与结构体里的具体类型比较得出。

一般32位系统:char 1字节,short 2字节,int 4字节,float 4字节,long 4字节,double 8字节,pointer 4字节

一般64位系统:char 1字节,short 2字节,int 4字节,float 4字节,long 4字节,double 8字节,pointer 8字节

示例1:

struct test1
{
  char a1;
  int b1;
  double c1;
}

a1 0开始对齐(char占用1字节,b1从4开始对齐,按规则2,a1后面需填充3字节),共占用4字节

b1 4开始对齐(int占用4字节,按规则2,从4开始对齐),共占用4字节

c1 8开始对齐(double占用8字节,按规则2,从8开始对齐),共占用8字节

总共4 + 4 + 8 = 16字节,按照规则3,对齐数为 double大小 与预设值(vs中默认8)较小值(应为8)

所以,该结构体占用的总内存大小应为 16字节

示例2:

struct test2
{
  char a2;
  double b2;
  int c2;
}

a2 0开始对齐(char占用1字节,b2从8开始对齐,按规则2,a2后面需填充7字节),共占用8字节

b2 8开始对齐(double占用8字节,按规则2,从8开始对齐),共占用8字节

c2 16开始对齐(int占用4字节,按规则2,从16开始对齐),共占用4字节

总共8 + 8 + 4 = 20字节,按照规则3,对齐数为 double大小 与预设值(vs中默认8)较小值(应为8)

所以,该结构体占用的总内存大小应为 24字节

对比示例1和示例2可以看出,变量先后顺序的影响对应的偏移位置,从而导致总内存占用发生变化

那么如何自定义内存对齐呢?使用用预编译命名,如下所示:

#pragam pack(n) (按照n个字节对齐)

struct test2
{
  char a2;
  double b2;
  int c2;
}

#pragam pack() (取消自定义对齐)

1、空类

class A {}

sizeof(A);  // 1

由于空类也可以实例化,那要如何区分呢,编译器通常会插入一个缺省字节,

2、带有虚函数的类

class B
{
public:
    virtual int test() = 0;
}

sizeof(B); // 4
在孤独中思考,在思考中成熟,在成熟中升华
原文地址:https://www.cnblogs.com/laogaoyang/p/5728299.html