还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte;但是实际上,通过运行程序得到的结果是8 byte,这就是内存对齐所导致的。 //32位系统 #include<stdio.h> struct{ int x; char y; }s; int main() { printf("%d...
编译器之所以要内存对齐,是为了更加高效的存取成员 c,而代价就是浪费了3个字节的空间。 除了结构体,变量也会进行内存对齐,请看下面的代码: #include<stdio.h>#include<stdlib.h>intm;charc;intn;intmain(){printf("&m: %X\n&c: %X\n&n: %X\n", &m, &c, &n);system("pause");return0;} ...
每个元素自身大小(也就是在内存占用内存大小) C结构体默认对齐规则 结构体第一个成员首地址为0 每个成员的首地址是自身大小的整数倍 如果结构体的成员是结构体,那么对齐位置是结构体成员中所含最大类型的整数倍 修改C结构体默认对齐规则 #pragma pack(push, <对齐字节数>) // 开始自定义对齐字节 #pragma pack...
第二个成员n,类型为int,小于默认对齐数8,则对齐数为4,而c1只是占用了一个字节,如果直接从c1后面开始存放n的话最终占用5个字节,违反了第二规则的最大对齐数整数倍,要想存放位置为整数倍最大对齐数,那只能从4位置开始存放,到7位置,从0到7为8个字节空间,符合最大对齐数的整数倍规则,算下来一共占用了...
变量b是int类型,根据第二个规则,可得 对齐数 = (4 < 8) = 4,所以对齐到结构体内存地址为4的地址处 变量c是double类型,同上,可得 对齐数 = (8 = 8) = 8,所以对齐到结构体内存地址为8的地址处 从图中可以清晰看出,结构体每个变量的内存使用情况。现在结构体已经占用了16个字节,那么总结构体的大小为最...
🌈在我们没学结构体内存对齐这部分知识前,我们肯定是按照以前计算内存大小的办法计算的。 printf(“%d”, sizeof(struct S1));计算类型大小而S1里面的类型有: int char char这三个加起来的大小不就是4+1+1 6个字节嘛!结构体S2和S1 包含的类型都是一样的那也就是6个字节了,可真的是这样吗?
这个对齐系数规定了所有int类型的变量默认情况下在内存中的地址必须是4的倍数(能被4整除)。也可以直接求得一个变量或者它的数据类型的对齐系数,比如下面的代码:#include <stdio.h> #include <stdlib.h> #include <stdalign.h> int main() { printf("char类型对齐系数:%d\n", alignof(char));printf("...
此外,CPU还不能跨内存区间访问。🧩 对于32位总线来说,CPU一次只能访问0x00-0x03或者0x04-0x07这两个内存区间。假设有一个结构体Foo,其中包含一个char类型的变量c和一个int类型的变量a。如果我们不进行字节对齐,想要访问变量a,需要首先读0x00-0x03,取0x01-0x03的内容,再读0x04-0x07,取0x04的内容,再把...
为了满足内存对齐的要求,编译器会在数据成员之间插入一些不需要的字节,这些字节称为填充字节。 填充字节的作用是保证数据成员存储在对齐的边界上,从而保证内存访问的效率和安全性。填充字节的数量取决于数据成员的大小和对齐边界的大小。 内存对齐的原理 内存对齐的原理是在变量之间插入填充字节,使得变量按照对齐方式排列。