结构体内存对齐

不同数据类型占用字节图

2251862-19673aeab7ce44b2-2.jpg

内存对齐的原则

1、数据成员对齐规则: 结构(struct)(或联合(union)的)数据成员,第一个数据成员放在 offset0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说数组,结构体等)的整数倍开始(如int为4字节,要从4的整数倍地址开始存储)

2、结构体作为成员: 如果一个结构体有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a 里存有struct b, b里有 char, int ,double等元素,那b 应该从8的整数倍开始存储。)

3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是内部最大成员的整数倍,不足要补齐

iOS获取内存大小的三种方式

sizeof: 是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。在编译阶段 就会确定大小
class_getInstanceSize: 这个方法由runtime提供api,用于获取实例对象所占的内存大小,本质是获取实例对象中成员变量的内存大小

(:如自定义类或继承关系 属性的多少变化而变化,如单纯的继承NSObject并且没有任何属性 打印为8 因为 有隐藏 isa 万物皆对象,而对象的本质为 继承 objc_object 的结构体 它就是对象模板)

malloc_size: 获取系统实际分配的内存大小(16字节对齐)

: 我们知道alloc 流程 最重要的三部曲
cls->instanceSize:计算需要开辟的内存空间大小(这里有一个算法为16字节对齐)
calloc:申请内存,返回地址指针
obj->initInstanceIsa:将 类 与 isa 关联

结构体内存对齐

首先创建 3个结构体 这三个结构体内部参数类型 都一样 只不过 是顺序不一样

[图片上传中...(截屏2020-09-15下午2.17.31.png-4046a7-1600150682775-0)]
{
    char a;  //1
    double b;//8
    int c;   //4
    short d; //2
}Mystruct1;


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


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

根据内存规则 我们画图来分析

截屏2020-09-15下午1.55.36.png

分析: ofsize 0 开始 存储char类型占一个字节的a ; b要存储了 首先分析自己自身多大 我是double类型的 我需要占8个字节 可是 如果从 a后面 开始 不满足自身 8 的倍数的地方 那我只能往下数 看来只能到 8的位置开始 容纳我的身体 【8 - 15 】 ; 该c出厂 存储了 我自身占用 4字节 我是int类型的 我只能先从16 开始 我的天 真幸运 正好符合我自身4字节的倍数 我可以 存储了 【16- 19】 d 出场了 我自身占 2个字节 得需要从20 位开始找能不能满足 我的倍数的规则要求 20 除 2 可以的 我也可以放下了 【20 - 21】
Mystruct1 结构体 承载了 21+1 个字节 突然 大喇叭喊出规则:结构体的总大小,也就是sizeof的结果,必须是内部最大成员的整数倍,不足要补齐:好的 那我里面最大的是 8 字节 那么 我现在 算出来 22 那么 补齐就好了嘛 不要激动 心里默念: 二 八 16, 不满足 ; 三八 24 满足啦 结束了。所以 Mystruct1 占用 24个字节空间

截屏2020-09-15下午2.17.31.png

分析: 从 0 的位置开始存 自身是double 类型的占用8个字节的 b【0-7】
a 是 占用一个字节的char类型 ,从 8的位置 满足自身1字节的倍数 所以 存储在8的位置【8】,c来了 首先 我自己是 int类型 我占用 4个字节 我只能从 9的位置开始存 可是 不满足 规则 必须是自己字节数的倍数,那我只能往下数了 9.10.11.12 咦!12是我的位置 那就从12开始【12-15】, d来了 首先想自己是 short类型的占用2个字节 我只能先从 16 的位置看 咦!这么巧 正好符合规则 是我的倍数 存这没毛病
Mystruct2 结构体 承载了 17+1 个字节 ,大喇叭又开始广播了:结构体的总大小,也就是sizeof的结果,必须是内部最大成员的整数倍,不足要补齐 ,好的村长 我补齐: 结构体最大的是 double占 用8个字节 我算出来18。 2*8 = 16 不满足 3 *8 = 24 村长 我满足了。所以 Mystruct2 占用 24个字节空间

截屏2020-09-15下午2.30.36.png

分析:从0 开始 存入一个 char类型的a d 来了 首先分析自己 是short类型 占用2个字节 那我如果从1 开始 那不是我的倍数 不满足规则。所以 往下看 2 好像 是我字节的倍数 ,好的存入 【2-3】 c来了我是 int类型的 占4字节 我只能从4开始存储 好像也满足 是我的自身4字节的倍数 ,好的存入【4-7】,b来了 嗯我是double类型 我自身占用8字节 我只能从 8号位置 开始存储 好像 8也是我的倍数 好的 存入【8-15】
`Mystruct3 结构体 承载了 15+1个字节,行了大喇叭别广播了 我知道了 我内部成员最大 的为8字节 必须是 8字节的整数倍 不足要补齐。
2*8 = 16 我满足了 ,所以 Mystruct3占用 16个字节

嵌套结构体

我们已经对结构体内存很明晰了 那么来个嵌套的

struct Mystruct3{
    char a;  //1  0
    short d; //2   [2 3]
     int c;   //4   [4 5 6 7]
    double b;//8  [8 9 10 11 12 13 14 15]
 }Mystruct3;
 


struct Mystruct4{
    char a;  //1
    int  b;  //4
    struct Mystruct3 struct3; //16
    
    
}Mystruct4;
 
 

上面我们分析了 Mystruct3 占用 16 个字节 那么 Mystruct4占用多少呢


结构体内存对齐.jpg

分析:
a 是占用一个字节的char类型 放在【0】
b是 占4字节的int类型 找到最近的 自身的占用字节的倍数的位置 为【4-7】
sturct3 是一个占用 16字节 的结构体 我们首先分析它最大的成员占多少内存 这里 为double 类型 占8个字节 所以应该 从8 的倍数开始存放第一个元素 上面的b占了【4-7】故只能从8往后数 正好8的位置 是 sturct3里最大元素的倍数 故第一个元素位置为【8】第二个元素为short类型占2个字节 所以需要从8 往后数正好满足自身的倍数 也就是【10 11】 第三个元素为double类型 占8个字节 所以需要从11 往后数满足8 的倍数 也就是【16 - 23】 因为 sturct3 是个结构体 也满足内存对齐原则 也就是 最大元素的倍数 sturct3占了 16字节 正好满足 对齐原则 a 占1 个 空白占3 b 占4 个 加在一起占 24个
sturct4 内存对齐 为 最大成员的倍数 最大成员 为struct3 里double 8 字节 所以
又是大喇叭所说的 内部成员最大字节 的倍数
所以 sizeof(Mysturct4) 最终 为 24
注意:

  1. 嵌套结构体 ,最大成员 不是 被嵌套的结构体本身大小 ,而是要看被嵌套的结构体元素 和当前结构体元素 谁大 谁最大就是谁的倍数
  2. 被嵌套的结构体 第一个元素占用位置 由 自身最大元素字节的倍数开始
截屏2020-09-24 下午10.37.20.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343