内存对齐时为什么结构体的最终大小需要是其最大成员大小的整数倍
来源:互联网 发布:信鸽分类信息软件 编辑:程序博客网 时间:2024/06/08 14:23
本文主要记录博主在研究内存对齐时遇到的一个疑问,及最终疑问的解答。
至于 什么是内存对齐、为什么要内存对齐、内存对齐的规则,网上一搜一大堆,这里就不记录了。
内存对齐时,结构体分配内存大小会满足两个条件:
1. 假设第一个成员的起始地址为0,每个成员的起始地址(startpos)必须是其数据类型所占空间大小的整数倍。
2. 结构体的最终大小必须是其成员(基础数据类型成员)里最大成员所占大小的整数倍。
其中,第一条起始地址特殊要求的原因(实际上就是内存对齐的原因)网上依然一搜一大把,主要是提高处理器访问内存的速度。
但第二条又是为什么呢?为什么要在所有成员都对齐以后又对整体大小做了要求?
查了一圈没有查到,最后在stackoverflow似乎找到了答案。
贴上原文地址:http://stackoverflow.com/questions/10309089/why-does-size-of-the-struct-need-to-be-a-multiple-of-the-largest-alignment-of-an
以下是看完帖子后的个人理解,若是不对还请各位指出。
个人理解:第二条实际上还是为了内存对齐,如果没有第二条来善后,那第一条的工作就有可能白做了。举个例子
struct st{ int32_t a; int8_t b;};struct st arr[N];
结构体 st 如果在最后没有进行填充则应该是5个字节,若做了填充则是8个字节。而底下数组arr的地址分配则会受到结构体 st 大小的影响。
假设数组的起始地址为0,那么
st 为5字节时,arr[0] 占用 0-4,arr[0].a的startpos为0,arr[0].b的startpos为4;arr[1] 占用 5-9,arr[1].a的startpos为5,arr[1].b的startpos为9。可以看到arr[1]的内部成员a并没有对齐(startpos不是其数据类型大小的整数倍),借用帖子里的话 arr[1].a 会cross lines。
st 为8字节时,arr[0] 占用 0-7,arr[0].a的startpos为0,arr[0].b的startpos为4;arr[1] 占用 8-15,arr[1].a的startpos为8,arr[1].b的startpos为12。依次类推数组里所有结构体成员及所有结构体的内部成员都会对齐。
因为基础数据类型的数据大小无非就是1 2 4 8 16字节,若结构体的总大小是最大基础成员大小的整数倍,那么也就一定是其他任一基础成员大小的整数倍,那么每个结构体的startpos就一定是其任一基础成员大小的整数倍 ,这样的话,两条规则结合在一起就保证了所有基础类型数据、非基础类型数据全部对齐。
- 内存对齐时为什么结构体的最终大小需要是其最大成员大小的整数倍
- 结构体的大小与内存对齐
- 结构体的大小(内存对齐)
- 结构体内存对齐规则总结-整体单个排列/成员之间没有边界只有最后的填充/最后是最大类型整数倍
- 内存对齐 结构体大小 内存空洞的分析
- 关于结构体的大小(内存对齐)
- C++ 内存对齐 (计算结构体的大小)
- 结构体的大小与内存对齐规则
- 【牛客 题库】 类的大小 联合体的大小 结构体的最大对齐数
- 类/结构体指针 描述其大小的内存位置
- 结构体的大小与内存对其
- 结构体的大小、元素的对齐
- 结构体对齐和类的大小
- 数据对齐 & 结构体的大小
- 结构体大小的计算,对齐
- 计算结构体的大小(对齐)
- 结构体内存大小的求法(内存对齐)
- struct的成员对齐问题-结构体实际大小问题
- MySQL基础知识
- webrtc之signal机制
- [勇者闯LeetCode] 125. Valid Palindrome
- 算法系列—计算阶乘
- 基础头文件
- 内存对齐时为什么结构体的最终大小需要是其最大成员大小的整数倍
- 445端口,修不完的BUG
- H5新标签 定义动画
- OpenCV3.2.0+VS2017环境配置与常见问题(巨细坑爹版)
- 从paxous到zookeeper
- java反射(对象拷贝)
- myeclipse启动tomcat停在 信息: Initializing Spring root WebApplicationContext
- Machine Learning第八讲[非监督学习] --(三)主成分分析(PCA)
- No qualifying bean of type xxxxx is defined