内存对齐

作者: 片片碎 | 来源:发表于2018-05-17 15:48 被阅读57次

内存对齐

一种提高内存访问速度的策略,cpu在访问未对其的内存需要经过两次内存访问,而经过内存对齐一次就可以了。


内存对齐系数

每个特定平台上的编译器都有自己的默认“对齐系数”(32位机一般为4,64位机一般为8),通常为4或8的倍数,

设置对齐参数: #pragma pack(n) ,n为对齐系数,不想对齐可以设置为1,设置为0,也表示为使用默认对齐

取消自定义字节对齐方式,使用默认对齐方式: #pragma pack()


sizeof

它的基本作用是判断数据类型或者表达式长度,要注意的是这不是一个函数,而是一个C++中的关键字!字节数的计算在程序编译时进行,而不是在程序执行的过程中才计算出来!


类型的长度与数据成员对齐

char  //1

short //2

int //4

long // 64bit 8 32bit 4

double //8

*// 64bit 8 32bit 4


struct或union成员对齐规则如下:

对齐规则如下:

原则一:存放的首地址偏移量 %  min(当前类型大小,对齐系数) == 0,假设对齐系数为8

            char  size = 1,min = (8,1) = 1,那么存放的首地址可以是任意地址 ,即首地址偏移量 %min == 0

          short  size = 2,min = (8,2) = 2,那么存放的首地址可以是0,2,4,6…… ,即首地址偏移量 %min == 0

            int      size = 4,min = (8,4) = 4,那么存放的首地址可以是0,4,8,12…… ,即首地址偏移量 %min == 0

            double size= 8,min = (8,8) = 8,那么存放的首地址可以是0,8,16…… ,即首地址偏移量 %min == 0

            long size= 8,min = (8,8) = 8,那么存放的首地址可以是0,8,16…… ,即首地址偏移量 %min == 0(64bit 8,32bit 4)

            long long size= 8,min = (8,4) = 4,但是内存的存储按照4字节来,即即首地址偏移量 %min == 0

            *  size = 8,min = (8,8) = 8,那么存放的首地址可以是0,8,16…… ,即首地址偏移量 %8 == 0 (指针,oid,或有类型的int,long,char...,都是如此,32bit 4)

            数组,size就是其对应类型的szie,比如char buffer[4],szie =1,min(8,1)= 1

原则二:结构体整体对齐,也称作二次对齐,结构体整体大小 % min(当前类型最大的大小,对齐系数) == 0



例子:

/****************** void * 和指定类型的指针 ***************/

1-1.默认64bit系统,即对齐系数为8,void类型指针

struct {

    char a;

    void *b;

    char c;

} myStruct;

printf("sizeof %ld \n char %p\n void * %p char %p\n",sizeof(myStruct),&myStruct.a,&myStruct.d,&myStruct.c);

结果:sizeof 24

char  0x1006826b8  //1+7

void * 0x1006826c0 //前面需要补齐8的整数倍 8

char    0x1006826c8 //1

1+(7)+8+1 = 17,17%min(8,8) = 1,需要补齐7,17+7 = 24

1-2.默认64bit系统,即对齐系数为8,char类型指针

struct {

    char a;

    char *b;

    char c;

} myStruct;

结果:sizeof 24

char  0x1006826b8  //1+7

char * 0x1006826c0 //前面需要补齐8的整数倍 8

char    0x1006826c8 //1

1+(7)+8+1 = 17,17%min(8,8) = 1,需要补齐7,17+7 = 24

1-3.默认64bit系统,即对齐系数为8,int类型指针

struct {

    char a;

    int *b;

    char c;

} myStruct;

结果:sizeof 24

char  0x1006826b8  //1+7

int * 0x1006826c0 //前面需要补齐8的整数倍 8

char    0x1006826c8 //1

1+(7)+8+1 = 17,17%min(8,8) = 1,需要补齐7,17+7 = 24

/****************** 数组:大小为其类型的大小****************** /

2-1.默认64bit系统,即设置系数为8

#pragma pack(8)

struct {

    char a;

    int b[6];

    char c;

} myStruct;

结果:sizeof 32

char    0x1006e66b8  //1 +3

  int[]    0x1006e66bc // 4 *6 = 24

  char  0x1006e66d4  //1

min = min(8,4) = 4;

1+(3)+24+1 = 29 ,29%4 = 1,需补3  29+3 = 32

2-2.默认64bit系统,即设置系数为8

#pragma pack(8)

struct {

    char a;

    char b[6];

    char c;

} myStruct;

结果:sizeof 32

char    0x1006ba6b8  //1

char[]    0x1006ba6b9 // 1 *6 = 6

  char  0x1006ba6bf  //1

min = min(8,8) = 8;

1+6+1 = 8

/****************** 内存对齐系数设置****************** /

3-1.默认64bit系统,即设置系数为4

#pragma pack(4)

struct {

    char a;

    int b;

    char c;

} myStruct;

结果:sizeof 12

char 0x1006926b8  //1 +3

  int    0x1006926bc // 4

char 0x1006926c0  //1

min = min(4,4) = 4;

1+(3)+4+1 = 9 ,9%4 = 1,需补3  9+3 = 12

3-2.默认64bit系统,即设置系数为8

#pragma pack(8)

struct {

    char a;

    int b;

    char c;

} myStruct;

结果:sizeof 12

char 0x1006926b8  //1 +3  min (1,8) = 1

  int    0x1006926bc // 4  min (4,8) = 4

char 0x1006926c0  //1  min (1,8) = 1

min = min(8,4) = 4;

1+(3)+4+1 = 9 ,9%4 = 1,需补3  9+3 = 12

/****************** double 和long****************** /

4-1 long long

#pragma pack(8)

struct {

    char a;

    long long b;

    char c;

} myStruct;

结果:sizeof 24

char 0x1006da6b8

long long  0x1006da6c0

char 0x1006da6c8

4-2 long

#pragma pack(8)

struct {

    char a;

    long b;

    char c;

} myStruct;

结果:sizeof 24

char 0x10068e6b8

long 0x10068e6c0

char 0x10068e6c8

4-3

#pragma pack(8)

struct {

    char a;

    double b;

    char c;

} myStruct;

结果:sizeof 24

char 0x10074a6b8

void * 0x10074a6c0

char 0x10074a6c8

相关文章

  • 2.iOS底层学习之内存对齐

    学习了内存对齐之后的疑问?? 1.为啥要内存对齐?2.内存对齐的规则?3.内存对齐实例分析。 内存对齐的目的 上网...

  • 内存对齐

    本次主要讨论三个问题: 什么是内存对齐 内存对齐的好处 如何对齐 内存对齐 内存对齐是一种提高内存访问速度的策略。...

  • 结构体内存对齐

    对象内存对齐 探讨的问题 1.什么是内存对齐?2.为什么要做内存对齐?3.结构体内存对齐规则4.源码内存对齐算法 ...

  • 内存对齐

    内存对齐 什么叫内存对齐内存对齐就是按照特定的规则对数据进行存储,一般编译器按照8字节对齐标准处理。内存对齐一般用...

  • iOS内存对齐

    这篇文章我们来探索一下iOS内存对齐的原理,在探索完内存对齐原理之后,你就会明白内存对齐的好处。 在讲述内存对齐时...

  • iOS 开发 内存对齐(练习)

    目录 内存对齐规则 对齐系数 面试题演练 一、内存对齐规则 (关于面试题中结构体内存对齐计算总结) 1.1、数据成...

  • 内存对齐

    在C语言柔性数组一文中,提到了内存对齐,于是想写篇文章总结总结内存对齐。 内存对齐 为什么需要内存对齐 计算机系统...

  • iOS底层探究 - 内存对齐

    目录1:内存对齐的原因2:内存对齐的规则3:结构体内存分配演练以及在iOS中对象成员的内存分配探索 一 :内存对齐...

  • 内存对齐

    知识点概要 OC对象内存对齐结构体内存对齐 OC对象内存对齐 计算内存大小的三种方式 1.sizeof:系统提供的...

  • C/C++内存对齐

    在面试或工作中,经常会遇到内存对齐的问题。这里结合我的理解谈一谈对内存对齐的理解。 1. 为什么要内存对齐,不对齐...

网友评论

  • SunnyDecember:网络发送数据,需要字节对齐吗
    片片碎:这个只是一种内存优化,你发送数据看找你们的协议来

本文标题:内存对齐

本文链接:https://www.haomeiwen.com/subject/szwbdftx.html