C语言对 字节对齐 struct结构体大小#pragma pack(一定能懂)

C语言对 字节对齐 struct结构体大小#pragma pack(一定能懂)

struct data_type1{
    char a;
    short b;
    int c;
};
struct data_type2{
    char a;
    int c;
    short b;
};

先看看上面两个结构体,如果有定义成对应的变量,它俩占内存空间是多少 ?如果你的答案是是相同,说明后面内容对你十分有用,一定会有收获的。

data_type1和data_type2结构体里的成员变量类型相同,两者的所占的空间应该是相同的,但是事实却不是如此。

经过实践编写代码输出的结果,却是这样的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vuYBLyUH-1633096788329)(image/image.png)]

为什么会出现这样的结果呢?

这是因为,编译器为数据进行了处理,做了字节对齐操作。又有疑惑?

什么是字节对齐?

现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常是4或8)的倍数 ,这就是所谓的内存对齐。大白话就是,各种数据类型都要一定的规则进行排列,而不是一个接一个的排放,这就是对齐。

结构体的字节对齐规则?

1、对于结构的各个成员,第一个成员位于偏移为0的位置,以后的每个数据成员的偏移量必须是 min(#pragma pack()指定的数,这个数据成员的自身长度)的倍数。(默认#pragma pack(4 )).

2、在所有的数据成员完成各自对齐之后,结构或联合体本身也要进行对齐,对齐将按照 #pragram pack 指定的数值和结构或者联合体最大数据成员长度中比较小的那个。

说了那么多,我以前面的例子说明。

struct data_type1{
    char a;
    short b;
    int c;
};
struct data_type2{
    char a;
    int c;
    short b;
};

data_type1:char 占1个字节,偏移量是0;short占2个字节,min(4,sizeof(short)所以short的偏移量是2的整数倍,此时short的偏移量是1,要是2的整数倍,则需要在char后面补上一个字节,空数据;int占四个字节,min(4,sizeof(int)所以int的偏移量是4的整数倍,此时int 的偏移量2+2=4,刚好是4的整数倍;此时一共占了2+2+4=8个字节,但是还有结构体本身的对齐,min(4,结构体成员里最大数据类型int)=4;所以总体的字节数是4的整数倍,后面不需要添加字节。所以占用8个字节。

data_type2:char 占1个字节,偏移量是0;int占4个字节,min(4,intsizeof(int)所以int的偏移量是4的整数倍,此时int的偏移量是1,要是4的整数倍,则需要在char后面补上3个字节,空数据;short占2个字节,min(4,sizeof(short)所以short的偏移量是2的整数倍,此时short的偏移量4+4=8,刚好是4的整数倍,不需要添加字节;此时一共占了4+4+2=10个字节,但是还有结构体本身的对齐,min(4,结构体成员里最大数据类型int)=4;所以总体的字节数是4的整数倍,10不是4的整数倍,后面需要添加2个字节。所以占用12个字节。

怎么更改C编译器的缺省字节对齐方式?

使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。

#pragma pack (1)//开始
struct data_type1{
    char a;
    short b;
    int c;
};
struct data_type2{
    char a;
    int c;
    short b;
};
#pragma pack ()//结束

两者的结构体都是以1字节进行对齐,不管顺序怎样,都占7个字节,但是有一点,与之前不修改字节对齐方式对比,cpu访问内存的效率降低。

为什么效率低,还要这样干?

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐。

为什么要字节对齐?

1、减少cpu访问变量的次数,cpu可以更快的读取数据

2、合理的使用字节对齐,可以节省内存的大小。

3、减少 cpu 访问数据的出错性(有些 cpu 必须内存对齐,否则指针访问会出错)。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小昭dedug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值