内存对齐问题
来源:互联网 发布:平民护肤品推荐 知乎 编辑:程序博客网 时间:2024/06/06 04:50
从网上看了几篇关于内存对齐的文章,以下是我的理解:
首先需要知道 可以通过以下命令设置对齐系数: #pragma pack(n) //n可以取1,2,4,8,16等,默认一般是8或16
先看一下内存对齐的规则:
1、 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移位置分两种情况:
#pragma pack(n) 中的n(对齐系数) 与 要定位的数据成员的自身长度 比较
(1) n较小: 该成员偏移的起始位置(相对于第一个成员的偏移位置) 需要为n的整数倍
(2) 该成员的自身长度较小: 该成员偏移的起始位置(相对于第一个成员的偏移位置) 需要为自身长度的整数倍
2、 在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个数值进行。最后结构体的大小应该为较小数值的整数倍.
了解了对齐规则,下面举几个例子:
struct st1
{
char a ;
short c ;
};
{
short c ;
char a ;
int b ;
;
此处假设 char占1字节, int占4字节 ,short占两个字节#pragma pack(4)时:
sizeof(st1) = 12 sizeof(st2) = 8
首先分析结构体st1
根据上述规则1
成员a占一个字节起始位置为0,
成员b占4字节, 与对齐系数n比较,大小相同. 所以成员b的起始位置应为4的整数倍由于a只占一个字节,所以 需要补三个空字节, b的起始位置为4
成员c占2个字节, 与对其系数n(4)比较, c长度较小, 成员c的起始位置为2(c所占字节)的整数倍 c的起始位置为 8(a占1个字节,后面补了3个,b占4个, 所以前面所占位置为0-7 , 下一位置是8刚好是2的整数倍)
经规则1分析后 结构体内存存储为: a000 bbbb cc 0代表补齐的内存
根据上述规则2,
整个结构体也需要对齐, st1中最大成员大小为4(int) 与n(4) 大小相同,所以结构体大小应为4的整数倍, 目前大 小为10, 还需要在后面补齐两位.
st1在内存中最终的存储为: a000 bbbb cc00 0位存储a , 1-3位补齐 , 4-7位存储b , 8-9位存储c , 10和11位补齐
下面分析结构体st2
规则1:
c占2字节 起始位置为0, 0-1位存储c
a占1字节 1<n(4) 所以a的起始位置为1(较小)的整数倍, a的起始位置为2,2位存储a
b占4字节 4=n b的起始位置为4的整数倍, b的起始位置为4,第3位补齐 4-7位存储b
规则2:
st2中成员最大为4, n也为4 , 所以结构体大小应为4的整数倍, 由于此时结构体大小刚好为8,所以不需要补位,
综上st2的存储为 cca0 bbbb
再谈论一下#pragma pack(2)时:
sizeof(st1) = 8 sizeof(st2) = 8
结构体st1:
规则1:
a占1字节 起始位置为0,0位存储a
b占4字节 4>2(前面定义的对齐系数) , 所以b的起始位置应为2(4与2较小的)的整数倍, 1位补位,2-5位存储b
c占2字节 2=2 , c的起始位置为2的整数倍,6-7位存储c
规则2:
st1中成员最大为4 , n=2 , 4>2 ,所以结构体大小为2的整数倍
n=2时结构体st1的存储为 a0bbbbcc
结构体st2:
规则1:
c占2字节 起始位置为 0,0-1位存储c
a占1字节 1<2 a的起始位置为2,2位存储a
b占 4字节 4>2 b的起始位置为2的整数倍,b的起始位置为4,3位补位,4-7位存储b
规则2:
结构体st2的最大成员大小为4, 4>2 结构体大小为2的整数倍
综上结构体st2的存储为 cca0bbbb
其他情况都是根据那两条规则分析就可以了
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 关于内存对齐问题
- 内存对齐问题
- 内存对齐问题
- 内存对齐问题 zz
- 内存对齐问题分析
- 内存对齐的问题
- Windows内存对齐问题
- 内存对齐的问题
- 内存对齐问题
- 内存对齐问题
- BNU19907 UVA11489 Integer Game
- 无线方式组网 - ZigBee、GPRS在充电桩中的应用
- linux 常用命令
- 算法之素数的快速筛选两种方式
- 鹅厂安卓面试
- 内存对齐问题
- HTTP Referer(页面统计/资源防盗链)
- mysql 表约束
- linux系统crontab执行jar包的shell脚本
- Android Studio多工程引用同一个library项目配置方法
- Unity AssetBundle须知
- 获取jqGrid中选中行的数据以及 jqGrid获得所有行数据的方法
- Java并发编程实战笔记(3)- 多线程并发编程模型
- 悲观锁乐观锁