C/C++ 字节对齐

本文深入探讨C/C++的字节对齐规则,指出网上普遍存在的错误观点,并通过实验验证,证明了对变量起始地址的假设并不总是正确。作者详细解释了结构体和变量的对齐规则,以及如何通过调整对齐参数影响内存布局。通过实例展示了不同编译环境下结构体的内存分布,阐述了如何满足地址对齐的规则,以确保高效的内存访问。
摘要由CSDN通过智能技术生成


结构体的字节对齐是我很早就想全面了解一下的东西,这个东西本质上是和硬件相关的,本来要想真正全面了解的话必须得知道CPU的结构、内存的结构、CPU指令是如何执行的等这些硬件层的东西才行,并不是说了解几个寄存器写两句汇编码就可以的,和这个没联系。在尝试了几次之后,迫于个人能力问题,无奈之下只好放弃深层次的了解,只能了解一下字节对齐的规则,至于为什么要对齐的话题,大概也就只能从网络上那几句肤浅的话了解到了:


“一些平台对某些特定类型的数据只能从某些特定地址开始存 ……最常见的是如果不按照适合其平台要求对 数据存放进行对齐,会在存取效率上带来损失……”


只是想了解字节对齐的规则也不是想象中那么容易的事情,对齐规则本身并不算复杂,而最困惑的是网上各种错误的文章,至少我看过的那几十篇包括一些重复的转载和引用,基本上是错的。当然,也并不是说他们错得多么的离谱,大致还是对的,只是一些困惑的地方从来没有人去证实,都自然而然的想当然了,而结果却是错误的。

所以我还是那句话,从来都不带怀疑和思考的精神去看别人的东西,从来不经过自己的证实就轻易相信,那么,误导了你也是你自己活该~~

我写这篇笔记,首先是要证明网上那些错误的地方,以及给出我自己的一些结论。然后就是给出我自己总结出来的一个字节对齐规则的版本。

 

1.  证明它是错的


我所说的他们那些错误的地方,基本上可以归结于一个问题上的错误,那就是对变量的起始地址的假设。


很多文章大概都有像这样的结论:


1. 数据项只能存储在地址是数据项大小的整数倍的内存位置上;

2. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

3. 对齐在N上,也就是说该数据的"存放起始地址%N=0


很明显,如果对数据存放地址的把握错误了的话,那么由此推断出来的地址对齐规则也就全都是错的了,而事实上也是如此。我研究这个课题 80%的时间都是花在这个上面,而真正的对齐规则一个下午应该就可以解决了。


当然,像上面的结论在一般情况下基本上是正确的,也就是说:


char变量的地址 %1 =0;

short变量地址 %2 =0;

int变量的地址 %4 =0;

double变量的地址 %8 =0


这里假设:


sizeof(char) = 1;

sizeof(short) = 2;

sizeof(int)=4;

sizeof(double)=8


这是 win32 平台上的实际值,此篇都以此假设为基础。


当这些变量是处于内存的数据区(或只读数据区)或者是从堆上分配出来的话,应该都是正确的,因为编译器和堆管理可能会帮你把这件事情做得很好,而程序员在代码里面基本上控制不了这些区域的变量的起始地址,实则我的多次实际测试也都符合上面的结论,即变量存放起始地址%N=0,结构体也符合首

  • 21
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值