C语言结构体_字节对齐

C语言_结构体 _ 字节对齐 - 详解

0 . 说明

​ 看滴水逆向视频总结笔记

​ 编译器VC++6.0

1.结构体__字节对齐的背景(本质)

​ 由于我们32位的计算机在处理数据时最喜欢4个字节4个字节的处理,这样效率最高,所以在堆栈中,是4个字节一排,方便计算机每次处理4个字节。

本机宽度:4个字节

​ 但是结构体在堆栈中分配一个连续的空间,一般会不等宽(char型数据一个字节,int型数据4个字节)。

设想一下:在堆栈的一排4个字节中,先为char分配一个空间,那int型数据占后面三个字节+下一排的一个字节。这样在堆栈分配空间时,的确是最省空间的,数据全挨在一起。

这种情况下,计算机要想调用这个int型数据,就要用两个堆栈地址。但是计算器为了提高效率,为了给这个int型数据 在堆栈中分配一个完整连续且在同一排的4字节空间,那么int型数据就不会占用第一排char型数据剩下的3个字节,而占用下一排完整的4个字节。

那这个char型数据在堆栈中占据的那一排空间就会空出3个字节,让一个char型数据占了4个字节,这就是字节对齐,这里是4字节对齐

​ 所以,字节对齐的本质就是:作为计算机本身,是想要空间还是要效率?显然在对于处理结构体这样特定的数据时,就会选择效率。

2.结构体__字节对齐的处理方式总结

​ 结构体的一个成员先占领一个堆栈空间,如果在这一排中剩下字节如果不能满足下一个成员的大小,那么下一个成员就会在下一排堆栈空间存放数据。

如果能满足下一个成员的大小的情况下,两者大小不到四的话,小的一方补齐字节,平均分配这一排堆栈4个字节。

3.4字节对齐__实例展示

​ 这里就用vc的内存演示,因为内存和堆栈本质上是一致的。

a.发生字节对齐

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

​ 总共为其分配了0xc个空间,但这四个成员的总体宽度只有8个字节。

​ 第一个成员stu.a发生字节对齐,char型数据占了4个字节。

​ 第三个成员stu.c也发生字节对齐,char型数据占2个字节。

b.改变书写顺序

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

​ 我们发现,同样成员的结构体,因为书写顺序不同,这里就这分配了8个内存空间,两排堆栈[ebp-8]、[ebp-4]正好满满当当存放着4个成员,并没有发生字节对齐

c.体会

​ 学会了字节对齐的概率后,发现不同的书写也会造成不同的空间分配,为减少不必要的浪费,即有效率同时节省空间,我们在书写的时候,一定要考虑字节对齐,合理安排书写顺序。

4.拓展

​ 以上将的字节对齐全是基于4字节对齐,除此之外还有1字节对齐2字节对齐8字节对齐16字节对齐

字节对齐是向下兼容的,也就是说,会自动适配结构体成员的宽度大小,选择最大的作为字节对齐的模式,

​ 一般VC++6.0是默认8字节对齐,而我们上述写的结构体中,宽度最大的成员是int型数据4个字节,所以自动适配按照4字节对齐

​ 右键项目文件->setting->C/C+±>Code Generation->Stuct menber alignment

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

​ 默认是8字节,可以更改,但是不建议更改。

5.8字节对齐实例展示

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

可以发现

  1. 8字节对齐的方式,在内存空间中都是8个字节为一个整体。

  2. 8字节对齐4字节对齐的基础上,以8个字节为整体。

  3. double型数据占8个字节,在内存中分别以两个4字节储存

例如:

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

6.强制转换 个别结构体 字节对齐的方式

#pragma pack(n)//n代表字节对齐的方式n = 1、2、4、8、16.
struct student
{
	char a;
	int b;
};
#pragma pack()

如果有有什么不懂或是我那个地方写的不对、不好的话,欢迎大家留言指正

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值