面试常考,项目易错!C/C++中的字节对齐( 二 )
按照规则对齐 , 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字节 , 只能拆分成两个4字节进行处理 , 所以这里规则对齐将判定该结构体最大数据类型长度为4字节 , 因此总长度为4字节的整数倍 , 也就是12字节 。
这个结构体在64位环境下所占内存空间为16字节 , 而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
#include
using namespace std;
#pragma pack(8)
struct Args
{
char ch;
double d;
short st;
char rs[9];
int i;
} args;
struct Argsa
{
char ch;
Args test;
char jd[10];
int i;
}arga;
int main
{
cout<<"Args:"<
cout<<""<<(unsigned long)
cout<<"Argsa:"<
cout<<"Argsa:"<<(unsigned long)
cout<<"Argsa:"<<(unsigned long)
return 0;
}
输出结果:
文章插图
改成#pragma pack (16)结果一样 , 这个例子证明了三点:
指针主要是因为32位和64位机寻址上,来看看例子
//编译器:
//来源:技术让梦想更伟大
//作者:李肖遥
#include
#include
using namespace std;
#pragma pack(4)
struct Args
{
int i;
double d;
char *p;
char ch;
int *pi;
}args;
int main
{
cout<<"args length:"<
cout<<"args1:"<<(unsigned long)
cout<<"args2:"<<(unsigned long)
return 0;
}
结果如下
pack48length3240args188args248
文章插图
内存对齐的规则1、数据成员对齐规则
结构或联合的数据成员 , 第一个数据成员放在 offset 为0的地方 , 以后每个数据成员的对齐按照 #pragma pack 指定的数值和这个数据成员自身长度中 , 比较小的那个进行 。
例如 struct a里存有 struct b , b里有 char , int, double 等元素 , 那 b 应该从8的整数倍开始存储 。
2、结构体作为成员
如果一个结构里有某些结构体成员 , 则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储 。
在数据成员完成各自对齐之后 , 结构或联合本身也要进行对齐 , 对齐将按照#pragma pack 指定的数值和结构或联合最大数据成员长度中 , 比较小的那个进行 。
- 研发|闽企制伞有“功夫”项目入选国家重点研发计划
- 建设|龙元建设中标中国移动宁波信息通信产业园二期施工项目
- 钢筋|海南国道G360文临公路项目引进钢筋智能“焊”将
- 名单|河南8个项目入选国家级示范名单
- 项目|Yearn帝国正在崛起,有多少DeFi项目开始瑟瑟发抖
- 合并|Andre Cronje主导批量「合并」DeFi项目,是好事情吗?
- 贵阳|捷顺科技(002609.SZ)中标贵阳智慧停车公共信息服务平台系统建设项目
- 建设|日海智能(002313.SZ)中标板障山山地步道项目线路一智慧化建设设计施工总承包项目
- 团队|为什么项目管理非常重要?
- 五金|我院承担的顺德区家居五金国际质量比对项目顺利通过成果验收