内存对齐原理

内存对齐的原则:

  1. 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第
    一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要
    从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,
    结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存
    储。
  2. 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从
    其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b
    里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
  3. 收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补⻬。

举个例子:

struct Struct1 {
    char a;     //1字节
    
    double b;   //8字节
    short c;    //2字节
    int d;      //4字节
} Struct1;

struct Struct2 {
    char a;     //1字节
    short b;    //2字节
    int c;      //4字节
    double d;   //8字节
} Struct2;


NSLog(@"Struct1占用内存大小:%lu",sizeof(Struct1));
NSLog(@"Struct2占用内存大小:%lu",sizeof(Struct2));

输出结果:
Struct1占用内存大小:24
Struct2占用内存大小:16

同样的变量,只是顺序不同,占用的内存不一样,这和内存对齐有关

  • 首先看Struct1和Struct2,先找到长度最大的变量,就是double占8字节,这样可以确定结构体是以8字节对齐的(内存大小是8的倍数)

先分析Struct1

  • a占1字节放在0号位置上
  • b占8字节但是1号位置不是8的整倍数,最近的整倍数位置是8,因此b放在8号位置上
  • c占2字节放在16号位置上
  • d占4字节但是18号位置不是4的整倍数,最近的整倍数位置是20,因此d放在20号位置上
    在这里插入图片描述

同理分析Struct2
在这里插入图片描述
扩展

struct Struct3 {
    int a;      //4字节
    char b;     //1字节
    int c;      //4字节
} Struct3;

struct Struct4 {
    struct Struct3 str3;
    struct Struct1 str1;
} Struct4;
NSLog(@"Struct4占用内存大小:%lu",sizeof(Struct4));

输出
Struct4占用内存大小:40

分析:
Struct3最大长度是4,Struct3整体是4字节对齐
Struct1最大长度是8,Struct1整体是8字节对齐
Struct1是8字节对齐的,12不是8的整数倍,因此Struct1从16号位开始
在这里插入图片描述
这里介绍获取内存的三种方式:

  • sizeof
  • class_getInstanceSize
  • malloc_size

sizeof

  1. sizeof是一个操作符,不是函数
  2. 我们一般用sizeof计算内存大小时,传入的主要对象是数据类型,这个在编译器的编译阶段(即编译时)就会确定大小而不是在运行时确定。
  3. sizeof最终得到的结果是该数据类型占用空间的大小

class_getInstanceSize

  • 用于获取类的实例对象所占用的内存大小,并返回具体的字节数,其本质就是获取实例对象中成员变量的内存大小

malloc_size

  • 获取系统实际分配的内存大小
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值