杂谈c语言——3.内存对齐

[复制链接]
发表于 2026-2-12 14:01:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
先看两个例子:
  1. typedef struct S {
  2.         int a;
  3.         double b;
  4.         char c;
  5. }S;
  6. typedef struct B {
  7.         int a;
  8.         char b;
  9.         double c;
  10. }B;
  11. int main() {
  12.         printf("S : %d\n", sizeof(S));
  13.         printf("B : %d\n", sizeof(B));
  14.         return 0;
  15. }
复制代码
效果为:
S:24;
B:16: 
可见差异,简单来说就是按照成员的界说序次,依次为其分配内存,分配内存的起始偏移位置应该是选定对齐数的整数倍,末了布局体变量所占巨细应该是成员最大对齐数的整数倍。 
1.对齐原则 

 内存对⻬规则

• 第⼀个成员在与布局体偏移量为0的地点处。

• 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地点处。

• 注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。

• VS中默认的对⻬数为8

• 布局体总⼤⼩为:最⼤对⻬数(全部变量范例最⼤者与默认对⻬参数取最⼩)的整数倍。

• 假如嵌套了布局体的环境,嵌套的布局体对⻬到⾃⼰的最⼤对⻬数的整数倍处,布局体的团体⼤⼩ 就是全部最⼤对⻬数(含嵌套布局体的对⻬数)的整数倍。
 
举例证明
  1. //练习1.
  2. struct A {
  3.         char c;
  4.         int i;
  5.         char b;
  6. };
  7. int main(){
  8.     printf("%d\n",sizeof(struct A));
  9.     return 0;
  10.     }
复制代码
   布局体成员变量分配内存的详细过程:

        1.起首:char c为第一个成员变量,遵照第一条规则,char c从偏移量0开始,占1个字节,指针指向下一个偏移地点1

        2.接下来存放int i, 但偏移地点 “1” 并不是对齐数4的整数倍
对齐数4来自(对齐数 = 编译器默认的一个对齐数 与 该成员巨细的较小值。)规则2,成员变量2是int范例,巨细为4字节,在VS中,编译器默认对齐数为8,8与4的较小值为4,以是成员变量2的对齐数为4。
那么指针须要移动到对齐数4的整数倍,即偏移量4地点处,开始存放int i 占4个字节,且偏移量1~3为空闲区,浪费了。

        3.接下来指针指向了偏移地点9,第三个成员变量char b的对齐数是1,偏移9是对齐数1的整数倍,符合条件,存放char b,占一字节,指针指向偏移10地点,由第三条规则可知,. 布局体总巨细为最大对齐数(每个成员变量都有一个对齐数)的整数倍,struct A最大对齐数是int i的对齐数4,那么现偏移10并不是对齐数4的整数倍,指针继续向下探求符合条件的偏移地点,末了指针指向偏移12,12是4的整数倍,符合规则,那么偏移竣事。

        效果共占12字节,内存中浪费了6个字节。
                           
 
 

 
2.强化训练
  1. struct S3
  2. {
  3.         double d;
  4.         char c;
  5.         int i;
  6. };
  7. struct S4
  8. {
  9.         char c1;
  10.         struct S3 s3;
  11.         double d;
  12. };
  13. int main(){
  14.     printf("%d\n", sizeof(struct S4));
  15.     return 0;
  16.     }
复制代码
由对齐原则可知sizeof(s3)=16;
盘算sizeof(s4)
 训练4.布局体内存分配过程:
   1.起首:char c1为第一个成员变量,遵照第一条规则,char c从偏移量0开始,占1个字节,指针指向下一个偏移地点1

   2.其次,第二个成员变量为布局体S3,分析是嵌套布局体,通过刚才对S3的布局体巨细可知是16字节,且S3中最大对齐数为8,通过规则4可知,现指针指向的偏移地点1并不是对齐数8的整数倍,以是指针须要向后跳转,直到指针指向偏移量为8的地点,才符合要求,开始存放struct S3成员变量,共16字节

    3.末了,指针指向偏移量为24的地点处,末了一个成员变量为double d,d的对齐数为8,偏移地点“24”是对齐数8的整数倍,以是开始存放double d,占8字节。
        如今指针指向了偏移量为32的地点,32是整个布局体最大对齐数8的整数倍,偏移竣事,布局体S4共占32字节,浪费了7个字节(偏移地点1~7)。
 
 
3.内存对齐的缘故起因 

 1. 不是全部的硬件平台都支持随意地点访问,有些硬件平台cpu只能从指定地点处读取指定巨细的数据,镌汰了非常抛出。
 
 

!!!!!!!!!!!
第一个由于内存对齐,固然ch只有1字节,但浪费3个字节 可以包管只读取到ch (不读到i)

第二个由于内存不对齐,会访问到ch和i的前3个字节的内容。会出标题
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表