首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

结构体在内存中的存储

结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。...如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体总大小是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。...***此时偏移量来到8,根据对齐规则3,结构体的总大小必须要是最大成员偏移量的整倍数。根据上面可知,char的偏移量是1,int的偏移量是4。...(struct stu)); return 0; } char a从0到1,int 从4到8,char c从8到9,结构体总大小要是最大结构体成员对齐数的整数倍。...a(0~1),struct stu1 s(4~12);int c(12~16); struct的最大对齐数是4,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,这里也就是对齐4; 四.为什么结构体不连续存储

10110

自定义类型:结构体+枚举类型+联合体+(内存对齐原则)

结构体内存对齐(重点)  光看文字很难理解,我们加上例题分析: 例题1: 第一个成员变量从地址0处开始,vs中默认的对齐数是8,char类型大小是1,选择其中较小值作为对齐数,所以是1。...然后结构体总大小要是最大对齐数的倍数,也就是要是4的倍数,所以自动增到12为止。  如图,最后对齐的大小就是12个字节了。 例题2:  例题2算得16....内存对齐这么复杂,为什么要有这东西呢?难道是为了给自己添加麻烦吗? 当然不是!  ...un的大小为4。当然,不可能就是最大成员的大小,那样也过于简单了。 其中的变量同时只能用一个,因为会互相改变值....依靠这个原理,我们又有了一种测试大小端的方法: 内存计算原则:        >=最大的变量大小                                         是最大对齐数的倍数

47930
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【C语言】自定义类型:结构体

    Linux中 gcc 没有默认对⻬数,对齐数就是成员自身的大小 结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的整数倍 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处...这就要涉及到我们的第3条规则:结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的整数倍    我们这个结构体中最大的对齐数是4,所以整个结构体的大小应该是4的倍数,而离...,是char类型的c2,大小为1,比VS默认对齐数小,所以它的对齐数是1,任何整数都是1的倍数,所以可以直接挨着c1存放c2,如图:    最后就是一个整型成员i,它的对齐数为4,所以必须对齐4...的倍数的偏移量,如图:    可以看到我们现在已经把三个成员分别记录下来了,总大小是8个字节,而我们的最大对齐数是4,而8是4的倍数,所以结构体的总大小就是8个字节    我们来看看代码运行结果...,我们需要找到嵌套的结构体的最大对齐数,我们在练习3已经讲过了,S3的最大对齐数是8,S3的整体大小是16个字节,所以要从8的倍数位置放下16个字节,如图:    最后一个成员是double类型的

    13610

    C语言---自定义类型:结构体

    嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整数大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍 //那么结构体是如何对齐的呢?...但是结构体的大小还不能因此判断 我们还要根据第三条进行判断 3.结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数, 所有对齐数中最大的)的整数倍 这三个成员的默对齐数是最大对齐数是...,构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处 //那么0-就是d占了 /* 对于c来说,c大小1个字节,vs默认对齐数是8,因为1的对齐数是1 那么只要是1的倍数就行了...嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处, 结构体的整数大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍 所以s3要对齐到字节的结构体内最大对齐数8的整数倍处 所以s3对齐到...在规则4中我们还说到 结构体的整数大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍 因为这哥结构体所有成员中对齐数里面最大对齐数是8 并且我们结构的大小最终还是要取决最大对齐数的倍数, 因为最大对齐数的倍数是

    5710

    【C语言高阶篇】结构体 —— 什么是内存对齐?

    也就是只要是在结构体里面的第一个成员。 他都存储在结构体变量偏移量为0的地址处。...图片展示: ✅ 结构体的内存对齐规则三 ⛳️ 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 也还是拿上面的结构体举例,前两个成员我们已经确定内存了!...那么这就和我们计算的12个字节完全不一样了! 其实最后一个成员就是这样存储的,但是由于: 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。...而这个结构体 3 个成员类型分别是 1 4 1,那么 结构体总大小就是 4的倍数 12 所以最后 3个字节也会算进去 ✅ 结构体的内存对齐规则四 ⛳️ 在讲规则四之前我们需要计算这结构体的存储字节以及...8 那么取最小值就是 4 而结构体的大小数所有成员最大的整数倍,那么就是8的倍数!

    1.1K20

    C语言自定义类型结构体与位段超详解

    VS 中默认的值为 8 Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。...然后c2:占一个字节,结构体大小直接+1(任何偏移量都是1的倍数,所以不需要额外偏移)。...最后,根据对齐规则3, 对齐数 = 编译器默认的一个对齐数 (以VS为例,8)与 该成员变量大小的最大值的较小值,这里显然对齐数是4,因此9的下一个对齐数的倍数是12,所以结构体的大小是12。..."%zd\n", sizeof(struct S2)); return 0; } c1不比多说,来看c2:char类型的大小是1,任何偏移量都一定是1的倍数,所以到了c2,结构体的大小是2。...因为24是8的倍数,所以d就再向后找8个地址,是32。 S4的偏移量是S4中所有除了S3以外的元素和S3的所有成员的大小中的最大值与默认对齐数8之间的较小值,是8,所以S4的大小是32。

    9210

    C语言结构体

    对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值,在VS2022中 默认是8                 Linux 和 gcc中没有默认设定参数,对其书加上成员自身的大小                ...如何对齐 struct A { char a;//1个字节 在内存中占0的地方 //1 //2 //3 int b;//4个字节 按照要在4的倍数上存在 站4-8 char c;//1个字节...占到第 9 的位置 //由于要是最大的字节的倍数 4的倍数 取最小倍数就是12 }; struct B { char a;//1个字节 0 char b;//1个字节 1 //2 //3...int c;//4个字节 4-7 4的倍数正好 8 }; struct C { int c;//4 0-3 char a;//1 4 char b;//1 5 因为要是4的倍数 占到8 }; struct...D { int a;//4 0-3 short b;//2 4-5 char c;//1 6 因为要是4的倍数 占到8 }; 注意:如果用#pragma 与粗粒命令,可以改变编译器的默认对齐数

    8910

    详解自定义类型:结构体,位段,枚举,联合

    结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 4....i占4个字节 ,它的偏移量必须为4的倍数 所以中间浪费了3个字节 然后c2是1个字节 谁都是它的倍数 整体大小为9 这个9不是最大成员int i的倍数 所以必须得扩大到它的倍数 为12...4.2 联合的特点 联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员) 我们来看他们的地址: 它们的地址都是一样的...联合的大小至少是最大成员的大小。...当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍 例如: #include union Un1 { char c[5]; int i; }; union

    13110

    【C语言】结构体详解

    与 成员变量的大小的较小值 --vs默认对齐数是8 --Linux中gcc没有默认对齐数,所以对齐数就是成员自身大小 i的对齐数是4,从4的倍数的偏移量开始存4个字节,c2的对齐数是1,从1的倍数开始存...1个字节 规则3 结构体总大小为结构体中所有成员对齐数的最大对齐数的整数倍 s中的成员最大对齐数是成员i的对齐数,为4,所以结构体的大小为4的倍数,当前大小为9,不是4的倍数,往后数,直到12,是4的倍数...,所以结构体大小为12个字节,打红色X的空间都是被浪费掉的,为什么要浪费,我们后面讨论 对前三个规则的练习 1.算结构体大小 struct s2 { char c1; char c2; int...我们先来看看第4个规则 规则4 如果结构体嵌套了结构体,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有对齐数的最大值(包括嵌套结构体的对齐数)的整数倍 S中的最大对齐数是...8,所以S要对齐到8的倍数 那么这个结构体的大小是不是就是32呢?

    9210

    【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参

    VS 中默认的值为 8 linux 中gcc没有默认对齐数,对齐数就是成员自身的大小 结构体总大小为最大对齐数(结构体中的每一个成员都有一个对齐数,所有对齐数中的)的整数倍。...如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。...S2最大对齐数是4,偏移量9,10都不对,当偏移量为11,从0到11刚好为12,为4的倍数(4*3=12)。所以S2总大小为12!...struct S4)); return 0; } 运行结果:32 第一个成员C1对应到偏移量为0处,大小为1,s3为结构体,s3的大小为16,根据第四条规则【如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处...,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。】

    38410

    【重新认识C语言----结构体篇】

    结构体的内存布局 4.1 内存对齐规则 为了提高内存访问效率,结构体的成员在内存中遵循对齐规则: 对齐数(Alignment):成员的大小与编译器默认对齐数中的较小值。...起始地址:每个成员的起始地址必须是对齐数的整数倍。 总大小:结构体的总大小是对齐数最大值的整数倍。...int i 对齐数为4,起始地址需是4的倍数,因此填充3字节(地址1~3),起始地址4。 double d 对齐数为8,起始地址8。...结构体与联合体(Union)的区别 结构体与联合体(union)的区别在于内存分配方式: 结构体:每个成员拥有独立的内存空间,总大小为所有成员大小之和(考虑对齐)。...联合体:所有成员共享同一块内存空间,总大小等于最大成员的大小。 7.

    9310

    【iOS进阶必学】 对象及结构体内存的探究

    ,则要是其子成员类型大小的整数倍 如果结构体 A 中包含另一个结构体 B,则 B 的起始位置要是 B 中最大成员的类型大小的整数倍 结构体最终的大小要是其最大成员的类型大小的整数倍,如果包含子结构体...,则最终的大小要是 max(自身最大成员大小,子结构体最大成员大小) 的整数倍 根据这个规则,我们来分析下上面题目的答案为什么是 24 和 16。...// 算下来大小为 24 + 16,共30字节,但需要是最大成员倍数,即 8 的倍数,最终结果为 32 字节 } BPStruct2; 2.2 如何读取结构体的汇编验证 2.1小节主要是结构体内存规则的介绍...下面看下进行内存对齐的情况: 这种对齐后的方式,会找到最大的度量,然后以这个度量为尺度,每次读取这么大的长度,有以下优点: 1、以最大长度读取时,不会超出结构体的内存空间,因为总长度是最大长度的倍数...2、各个成员起始都以自身倍数开始,就保证了以最大尺度读取时,每次都可以读取完整数据,而读取次数相对于逐个读会大大减少 结构体对齐之后,虽然占用存储空间大了一些,但是在读取效率上会大大减小,例子中不对齐需要读取

    53020

    掌握C语言结构体,开启编程新世界

    VS中默认的值为8 Linux中gcc没有默认对齐数,对对齐数就是成员自身的大小。 3. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的 整数倍。 4....int i占四个字节,虽然vs默认值为8,但是int类型更小(这时候的对齐数是4),既偏移量1,2,3,都不是4的倍数,所以int放在偏移量为4的位置,char c2的大小是1,偏移量8是一的倍数,所以可以放...都放完后,字节需要是最大对齐数的整数倍,所以就是8个字节。...这是因为结构体S3中有S1,S1中的最大对齐位置取决于自己的最大对齐数,而S1的最大对齐数是4,所以从偏移量为4可以开始放s1;double d占8个字节,偏移量16刚刚好是8的倍数;所struct S3...因此,位字段的大小可能不等于字段成员所占的位数之和。开发者需要了解编译器对位字段进行内存对齐的规则,以确保结构体的大小和内存布局符合预期。

    13310

    C语言----自定义类型:联合和枚举

    联合体的特点是所有成员共⽤同⼀块内存空间,这样一个联合变量的大小,至少是最大成员的大小 (因为联合至少的有能力保存最大的那个成员) 那么为什么这里是4呢?...联合体大小的计算 联合的大小至少是最大成员的大小。...当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍 //union Un //{ // char arr[5];//对齐数是1 // //这个数组放在这里,跟放5个char...return 0; //} /* 计算出的是8,所以我们得知联合体的大小不一定是最大成员的大小 联合体的大小至少是最大成员大大小 这个联合体最大对齐数是4 那么联合体的总大小一定要是4的倍数 这个联合体最大成员的大小是这个数组...2来算的 i的对齐数是4,那么最大对齐数是4 那么联合体的大小必须是4的倍数 虽然说联合体很节省空间,但是也不是那么很绝对的节省空间 */ 联合体的运用 /* 图书:库存量、价格、商品类型、书名、

    10510

    自定义类型:结构体

    中gcc没有默认对齐数,对齐数就是成员自身的大小 (3)结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大 的)的整数倍。...(4)如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。...例如,对于一个int类型(通常为 4 字节)的成员,它的存储地址必须是 4 的倍数;对于一个char类型(1 字节)的成员,它的存储地址只要是 1 的倍数即可。...明明s1与s2中的成员是一模一样的,为什么大小不同呢? 是不是很神奇?...4,与8比较后对齐数是4,而2,3不是4的倍数,因此跳过从4开始填写,向后占4个空间,这时总大小便是从0~7,占8个位置,根据第三条结构体总大小需要是成员中最大值的倍数,s1中成员最大值是4,8是4的倍数

    8410

    Go看源码必会知识之unsafe包

    没有任何字段的空struct{}和没有任何元素的array占据的内存空间大小为0,不同大小为0的变量可能指向同一块地址。...,除了int、uintptr这些依赖CPU位数的类型,基本类型的对齐值都是固定的,结构体中对齐值取他的成员对齐值的最大值,结构体的对齐涉及到内存对齐,我们在下面详细介绍。...除了结构成员需要对齐,结构本身也需要对齐,结构的长度必须是编译器默认的对齐长度和成员中最长类型中最小的数据大小的倍数对齐。...根据第二条规则,默认对齐值是8,字段中最大类型程度是24,取最小的那一个,所以求出结构体的对齐值是8,我们目前的内存长度是49,不是8的倍数,所以需要补齐,所以最终的结果就是56,补了7位。...对于内存对齐这里还有一最后需要注意的知识点,空struct不占用任何存储空间,空 struct{} 大小为 0,作为其他 struct 的字段时,一般不需要内存对齐。

    28020

    理一理字节对齐的那些事

    什么是字节对齐 计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的 倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制...那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。 对齐准则是什么 总的来说,字节对齐有以下准则: 结构体变量的首地址能够被其最大基本类型成员字节数大小所整除。...结构体每个成员相对结构体首地址的偏移都是成员大小的整数倍,如不满足,对前一个成员填充字节以满足。 结构体的总大小为结构体对最大成员大小的整数倍,如不满足,最后填充字节以满足。...c; short d; }; #pragma pack()/*还原默认对齐*/ 在这样的声明下,任何平台结构体test的大小都为11字节,这样做能够保证跨平台的结构大小一致,同时还节省了空间,...如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。 __attribute__ ((packed)),取消结构在编译过程中的优化对齐,也可以认为是1字节对齐。

    86030

    打造坚实的基础:C语言的结构体、联合体和枚举

    则e对其在4的倍数上, 则从4开始 f占一个字节,对齐数为1,放在一的倍数: 结构体大小为最大对齐数(4)整数倍,9不是4的倍数,则浪费9.10.11三块空间,最终大小为12 那么再做下面一道题...偏移量为0: char对齐数为1,放在一的倍数,对齐8 i对齐数为4,对齐在4的倍数上,及12 最大对齐数为8 16为8的倍数,所以 s3 大小为16 结构体嵌套 struct S4...我们来分析 c1为零偏移量,s3占十六个字节,但对齐位置则在8的倍数上即可, d对齐在8的倍数,从24开始 总大小及为最大对齐数(8)的整数倍,最终大小为32 为什么会有内存对齐?...编译器可能会在位段的末尾添加填充,以确保结构体的大小是其最大成员大小的倍数,这也符合一般的内存对齐原则 struct S { char a:3; char b:4; char c:5; char d:4...联合体的大小至少为其最大成员的大小,确保可以存储其中任何一个成员。联合体通常用于节省空间和处理不同类型的数据。 联合体通过关键字 union 定义。

    14410

    自定义类型:结构体(自引用、内存对齐、位段(位域))

    对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的 整数倍。...如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。...问:为什么结构体中的成员相同但占用的空间不同? 答:因为要对齐。 4.1偏移量计算的示例: 此处也有一个偏移量的概念。 在C语言中,偏移量通常用于描述结构体成员相对于结构体起始地址的内存位置。...d为双精度浮点型,占8个字节,对齐数为8个字节,从8的倍数的地址开始对齐。 S3为结构体,占16个字节,但最大对齐数为8个字节,所以从8的倍数开始对齐。 所以S3占16个字符,S4占32个字符。.... 4.4为什么存在内存对齐?​ 结构体的内存对齐是拿空间来换取时间的做法 1.

    23610

    内存对齐

    ,就可以理解为机器字长,也是平台对应的最大对齐边界,而数据类型的对齐边界是取类型大小与平台最大对齐边界中的较小的那个 类型 大小 RegSize int8 1 byte 8 byte int16 2...,不按照最大对齐边界或者最小对齐边界来考虑是为了减少浪费、提高性能 如何确定一个结构体的对齐边界 先确定每个成员的对齐边界,然后取最大值 type T stract { a int8...接下来是c,它要对齐到4字节。所有成员放好还不算完,内存对齐的第二个要求是结构体整体占用字节数需要是类型对齐边界的整数倍,不够的话要往后扩张。所以要扩充到相当地址23这里。...,才能保证数组中的每一个都是内存对齐的 内存对齐的第二个要求:结构体整体占用字节数需要是类型对齐边界的倍数,不够的话要往后扩张一下 举个特例 type T1 struct { a struct...地址对齐保证是:如果类型t的对齐保证是n,那么类型t的每个值的地址在运行时必须是n的倍数 零大小字段要避免只作为struct最后一个字段,会有内存浪费 参考 【Golang】这个内存对齐呀!?

    2.5K21
    领券