内存对齐的小妙招

内存对齐的小妙招

1、为什么需要内存对齐?

只是为了加快CPU对与内存的读取速度

2、内存对齐在结构体中是如何计算结构体大小的?

  1. **起始位置按照0x00来计算,**首先qt,vs,windows是默认按照八字节对齐的,linux32位是四字节对齐,64位是8字节对齐。还可以用#pragma (n)手动设置对齐字节数,n只能等于,1,2,4,8,16

  2. 除结构体第一个变量之外,其余所有变量的起始地址的偏移量必须是n的整数倍(你是默认对齐字节和变量本身大小,两个值之间的最小值)

  3. 结构体整体大小必须是实际对齐单位的整数倍(计算实际对齐单位是看结构体内最大的变量所占字节数和默认偏移量之间的最小值

  4. 比如

    struct test1
    {
    	short a;
    	char b;
    	char c;
    	char f;
    	int d;
    	double e;
    }x;
     printf("sizeof(struct test1)=%d\n",sizeof(struct test1));//结果是24

    运用上面得方法计算如下:
    char a为0x00-0x02;2字节

    char b为0x02-0x03;1个字节(偏移量是自身大小的整数倍就行所以是1)

    char c为0x03-0x04为1字节,

    char f为0x04-0x05;1字节,

    int d为0x08-0x11(int的偏移量必须是4的整数倍,所以只能为0x08-0x0b),

    double e;地址为0x16-0x23;(起始地址必须是8的整数倍),

    然后现在整个结构体大小是24,是最小对齐数8的整数倍,ok

    1. 结构体中有数组怎么解决,比如说加入char c[11],这里直接看作11个char去处理就好了

      比如

      struct test1
      {
      	short a;
      	char b;
      	char c;
      	char f;
      	int d;
      	double e;
      	char cc[11];
      }x;
       printf("sizeof(struct test1)=%d\n",sizeof(struct test1));//结果是40

      char a为0x00-0x02;2字节

      char b为0x02-0x03;1个字节(偏移量是自身大小的整数倍就行所以是1)

      char c为0x03-0x04为1字节,

      char f为0x04-0x05;1字节,

      int d为0x08-0x11(int的偏移量必须是4的整数倍,所以只能为0x08-0x0b),

      double e;地址为0x16-0x23;(起始地址必须是8的整数倍),

      char cc[11],地址就是0x23-0x33,

      这时整个结构体大小是34,不是最小对齐量8的倍数,所以,结构体大小应该是40

    2. 对于结构体中嵌套结构体怎么计算

      1、把嵌套进去的子结构体也当作一个变量,

      2、计算该结构体的偏移地址,应该是该结构体内的结构体内最大内存的变量和默认的偏移量的整数倍

      struct son
      {
      	short a;
      	char b;
      	char c;
      	char f;
      	int d;
      	double e;
      	char cc[11];
      }son;//大小是40
      struct parent
      {
      	char aa;
      	int bb;
      	son son1;
      };
      printf("sizeof(struct parent)=%d\n",sizeof(struct parent));//答案48

      计算:

      parent里面开始是

      char aa 为0x00-0x01;

      int bb;为0x03-07;

      struct son son1为0x07-0x47;所以大小是48

      总结就是:

      1、起始元素不用在意偏移量,其他元素的起始位置应该是(其自身大小和默认偏移量之间的最小值)的整数倍

      2、遇到数组,直接转化为n个重复的数组元素,如int a[13],直接看成 int a;int a;int a;…13个a,再用上面的规则去计算内存

      3、遇到结构体内嵌套结构体,就把子结构体先计算内存,再计算子结构体对于父结构体的偏移量应该是(子结构体中的最大内存元素和默认偏移量之间的最小值)。从而计算父结构体内存。

      附录:常用字节数(32位机):
      int 一个字 32位,4字节
      short 半个字 16位,2字节
      long 一个字 32位,4字节
      char 1字节
      float 一个字 32位 ,4字节
      double 两个字 64位, 8字节

你可能感兴趣的:(内存对齐的小妙招)