当前位置:网站首页>结构体的内存对齐问题
结构体的内存对齐问题
2022-08-10 03:29:00 【iccoke】
结构体的内存对齐
结构体的大小不是结构体元素单纯相加就行的,因为我们主流的计算机使用的都是32bit字长的CPU,对这类型的CPU取4个字节的数要比取一个字节要高效,也更方便。所以在结构体中每个成员的首地址都是4的整数倍的话,取数据元素时就会相对更高效,这就是内存对齐的由来。每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
结构体内存对齐规则:
第一个成员在结构体变量偏移量为0 的地址处。
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数与该成员大小中的较小值。vs中默认值是8 Linux默认值为4.
结构体总大小为最大对齐数的整数倍。(每个成员变量都有自己的对齐数)
如果嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍。
结构体内存对齐规则的应用
例如这里我们定义一个结构体,应用结构体内存对齐原则我们进行结构体大小的判断
struct Student {
short b;
char c;
int a;
long int d;
double g;
};
直接简单加法的话,这个结构体的大小应该是19;那么我们打印一下他的大小
实际上应该是24,那么我们是怎么得到这个24的呢
首先b先存入内存中,那么c存入时对于的地址就是2,时c的整数倍,那么c就可以存到3这个位置,然后再存入a,对应的首地址是3,不是int 的整数倍,我们就要在c后面浪费一个字节使其满足结构体的内存对齐规则,然后再存入d,地址是8,是long int的整数倍,最后再存入g,地址是12,不是double的整数倍,然后应该在d后面浪费4个四个字节以求满足结构体的内存对齐问题,然后最后在判断整个结构体的大小是不是结构体内最大基本类型和默认内存对齐数中比较小的数的整数倍,double 类型占8个字节,vs中默认结构体对齐数是8,所以大小应该是8的整数倍,我们判断为24是正确的,符合内存对齐的规则
那么对于嵌套的结构体我们又该如何计算呢,这里我们举一个例子
struct S1
{
double d;
char c;
int i;
};
struct S2
{
char c1;
struct S1 s3;
double d;
};
printf("%d\n", sizeof(struct S2));
那么这里的结果应该如何来看呢,应该是32,这里我们放到内存上来看就会比较清晰
当计算完得到结果之后一定要严格的按照结构体的内存对齐规则进行验证
//* #pragma pack(字节) 对齐方式开始 预处理指令
//* #pragma pack() 对齐方式结束 预处理指令
这个指令可以改变系统提供的默认对齐数
例如#pragam pack(1)
#pragma pack()
这个分别使用在结构体的前后,这样既可以让结构体的对齐书改为1使用
结构体实际上是牺牲空间换取时间上的便利
边栏推荐
- goland json.Marshal导致&变成\u0026
- 【科研绘图】琴图 +箱型图混合 matplotlib库和seabsorn库的使用
- 微信小程序相互跳转如何携带参数
- 【2022河南萌新联赛第(五)场:信息工程大学】【部分思路题解+代码解析】
- Take you to an in-depth understanding of the version update of 3.4.2, what does it bring to users?
- applet wxs
- 同样是初级测试,凭什么他比我薪资高 5000 块?
- 数据库中数据的正确性和相容性是什么
- Did not detect default resource location for test class xxxx
- 自定义训练,使用Generator dataset迭代数据报错
猜你喜欢
随机推荐
TCP协议之《ACK状态4种详解》
No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.
Flink学习15:Flink自定义数据源
ThreedLocal在单线程中的应用【获取在拦截器中登录的用户信息】
uniapp 路由与页面跳转
Embedded Sharing Collection 32
How does a new tester do functional testing?Test thinking is really important
leetcode-218.天际线问题
1413.Minimum Value to Get Positive Step by Step Sum
模型部署ONNX学习
如何将 @Transactional 事务注解运用到炉火纯青?
同样是初级测试,凭什么他比我薪资高 5000 块?
shell文本编辑awk
文件操作【c语言】
如何开启热部署Devtools
zabbix添加监控主机和自定义监控项
【网络迁移】Pytorch中的torch.is_tensor对应MindSpore哪个接口
C语言顺序表(源码)
TCP协议之《延迟ACCEPT》
常用类以及接口