面试常考,项目易错,长文详解C/C++中的字节对齐( 二 )
可以看到按照自然对齐 , 变量之间没有出现间隙 , 所以规则对齐也不用进行填充 , 而这里有颜色的方格有6个 , 也就是6个字节
按照规则对齐 , 6字节是此结构体中最大数据类型short的整数倍 , 因此此结构体为6字节 , 后面的空白不需理会 , 可以实际编译 。 一下运行 , 结果和分析一致为6个字节 。
double的情况我们知道32位处理器一次只能处理32位也就是4个字节的数据 , 而double是8字节数据类型 , 这要怎么处理呢?
如果是64位处理器 , 8字节数据可以一次处理完毕 , 而在32位处理器下 , 为了也能处理double8字节数据 , 在处理的时候将会把double拆分成两个4字节数进行处理 , 从这里就会出现一种情况如下:
typedef struct test_32{char a;char b;double c;}test_32;
这个结构体在32位下所占内存空间为12字节 , 而在64位环境下所占内存空间为16字节 , 原因就是上述的处理方式不同导致的 , 32位下只能拆分成两个4字节进行处理 , 所以这里规则对齐将判定该结构体最大数据类型长度为4字节 , 因此总长度为4字节的整数倍 , 也就是12字节 。
而64位判定最大为8字节 , 所以结果也是8字节的整数倍:16字节 。 这里的结构体中的double没有按照自然对齐放置到理论上的8字节倍数地址处 , 我认为这里编译器也有根据规则对齐做出相应的优化 , 节省了4个多余字节 。
这部分各位可以按照上述规则自行分析测试 。
数组对齐值为:min(数组元素类型,指定对齐长度).但数组中的元素是连续存放,存放时还是按照数组实际的长度.
如char t[9],对齐长度为1,实际占用连续的9byte.然后根据下一个元素的对齐长度决定在下一个元素之前填补多少byte.
嵌套的结构体假设
struct A{......struct B b;......};
对于B结构体在A中的对齐长度为:min(B结构体的对齐长度,指定的对齐长度).B结构体的对齐长度为:上述2中结构整体对齐规则中的对齐长度.举个例子
//编译器:来源:技术让梦想更伟大//作者:李肖遥#include
输出结果:
文章插图
改成#pragma pack (16)结果一样.这个例子证明了三点:
- 对齐长度长于struct中的类型长度最长的值时,设置的对齐长度等于无用.
- 数组对齐的长度是按照数组成员类型长度来比对的.
- 嵌套的结构体中,所包含的结构体的对齐长度是结构体的对齐长度.
//编译器:来源:技术让梦想更伟大//作者:李肖遥#include #include using namespace std;#pragma pack(4)struct Args{int i;double d;char *p;char ch;int *pi;}args;
结果如下| pack | 4 | 8 || —- | —- | —- || length | 32 | 40| args1 | 8 | 8 || args2 | 4 | 8 |内存对齐的规则
- 数据成员对齐规则结构(struct)(或联合(union))的数据成员 , 第一个数据成员放在offset为0的地方 , 以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中 , 比较小的那个进行 。 (例如struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.) 。
- 结构体作为成员如果一个结构里有某些结构体成员,则结构体成员要从其内部”最宽基本类型成员”的整数倍地址开始存储.(例如struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.) 。
- 徐福记联手JDL京东物流向数智化转型,首次落地智慧园区项目
- 运动计数开发项目的对抗赛:飞算全自动软件工程平台碾压传统模式
- 江北新区企业院士工作站技术攻关项目立项数位居南京第一
- 赞!盐城高新区4个项目入选省级项目立项!
- 威海高新区2项目获2020年度山东省重点研发计划(重大科技创新工程)立项支持
- 浙江公布首批“互联网+”医疗服务价格项目!适用各级公立医疗机构
- 168天封顶!投资56亿重点AI项目将在上海竣工,提供世界领先算力支撑
- 微软计划用Monarch项目取代Windows 10电子邮件客户端
- 先睹为快!青岛临空能源中心项目规划公示 总建面 16673.43㎡
- 仅用168天,商汤科技“新一代人工智能计算与赋能平台”项目结构封顶