内存对齐
来源:互联网 发布:告白墙源码 编辑:程序博客网 时间:2024/06/06 10:44
讨论
- 32-bit机器,一次总线访问最多32bit数据
- 32bit以内的数据,一次总线传输即可完成。
- 机器的设计:
- 32-bit机器,访问一个32-bit数据(int)
- 可以一次取8bit,共取4次,放到总线
- 一次取16bit, 共取2次,放到总线
- 一次取32bit, 取1次,放到总线
- 可见,机器为了实现效率,一定会在电路设计上做到:
- 地址线多宽,一次就能访问多长的数据,而不用改变电信号。
- 为了简便,干脆使访问地址都是宽度的整数倍
- 所以:
- 在32-bit机器上,访问的地址是4的倍数
- 在64-bit机器上,访问的地址是8的倍数
- 如果数据地址不是倍数的话,就需要再做移位运算
- 在这种存储方式下,时间效率最优
- 当然,你也可以给机器说,我放弃时间效率最优,因为我的存储空间捉襟见肘。机器说,好吧,那你来指定存放方式。于是就可以手动修改为2字节对齐,4字节对齐。但你不能说3字节对齐,char(1),short(16),int(32), 如果用3字节对齐,时间空间都牺牲了。
- 所谓以n字节对齐,相当于你把地址线宽度修改成了n,在地址线宽度n的情况下实现时间效率最优。
- 32-bit机器,访问一个32-bit数据(int)
说明
struct Stru{ char a; short b; char c;};
32-bit机器(4字节对齐),上述结构体size为6,如果变为
struct Stru{ char a; char c; short b;};
size为4.
看这段代码:
int main(void){ char a; char b; short c; printf("&a : %p\n", &a); printf("&b : %p\n", &b); printf("&c : %p\n", &c); return 0;}
打印:
&a : 0x7fff548fabfb&b : 0x7fff548fabfa&c : 0x7fff548fabf8
在内存中的地址顺序:c, a, b. 这与结构体不一样,结构体中实际顺序是书写顺序,但在这里不是。
调整一下顺序:
char a;short c;char b;
打印:
&a : 0x7fff546cdbfb&b : 0x7fff546cdbf7&c : 0x7fff546cdbf8
顺序: b, c, a
一般变量在存储时,由编译器决定顺序。 编译器会进行优化。
Questions
32-bit机器上,4字节对齐,char+short结构体怎么放?
假如char放在0x0000处,short放在0x0001吗?这样放似乎没有什么问题。
然而,struct可以构成结构体数组,来看看这会出现什么情况
图中斜线表示char, 方格表示padding.
可以看到,第一个short首地址偏移1, 第二个往后变成了2. 也就是说,在结构体数组中,成员变量偏移不确定。所以这种情况是一定要避免的。解决的方法就是(设n字节对齐):当成员变量小于等于n时,成员变量的地址是它宽度的整数倍. 结构体size为最大成员变量的整数倍。 这样,在上述情况中,short就总是偏移2了。
32-bit和64-bit机器上,下面结构体的大小
#include <stdio.h>//#pragma park(4)struct Str{ char a; long b; char c;};int main(void){ struct Str st; printf("size of struct st: %lu\n", sizeof(st)); return 0;}
64-bit: size of struct st: 24
32-bit: size of struct st: 16
我用的64bit机器,所以4字节对齐时,我加上#pragme pack(4)
下面解释一下:
根据上面的结论:当成员变量小于等于n时,成员变量的地址是它宽度的整数倍。结构体size为最大成员变量的整数倍。 当n = 8
, 结构体为8×3 = 24.
当n = 4
, long
大于n,成员变量的地址应是4的整数倍,结构体size为4的整数倍。这时4×4 = 16.
0 0
- 关键字 对齐 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- 内存对齐
- appStore上传苹果应用程序软件发布流程
- angular模块控制器分离入门一
- UnityAPI翻译——VRDevice
- shell中各种括号的作用()、(())、[]、[[]]、{}
- OpenGL ES 学习教程(四) 买来墙纸,给立方体贴上!
- 内存对齐
- 关于redis、memcache、mongoDB 的对比
- android5.0应用显示安装未完成问题解决方案
- UVA 11997 - K最小的金额 (DP&转换&&优先队列) 好题
- linux管道pipe
- iOS页面间的几种传值方式
- 【PR系列之002-1104959】Google输入法建议词列表PopupWindow遮挡输入词,建议词列表PopupWindow无法上下滑动
- js 等待几秒 每隔几秒 执行
- 多媒体切片与http协议传输