weitom1982
向各位技术前辈学习,学习再学习.
posts - 299, comments - 79, trackbacks - 0, articles - 0
IT博客
::
首页
::
新随笔
::
联系
::
聚合
::
管理
字节对齐问题的一个例子和讨论。(转)
Posted on 2006-03-21 09:52
高山流水
阅读(876)
评论(0)
编辑
收藏
引用
所属分类:
计算机基础知识
老师提出一个很有意思的问题:
class
b
{
char
c1;
long
l;
char
c2;
double
d;
}
;
与
class
b
{
char
c1;
char
c2;
long
l;
double
d;
}
;
在存储的时候用的空间是不一样大的,前者是24,后者是16,为什么?
-------------------------------------------------------------------------------------------------------------------------
我在自己的机器上也运行了,的确如此,我知道16是怎么来的, char是2,long是4,double是8,2+2+4+8=16,而24我就太明白了,说地址是4字节的,char是2,要空两个字节,那第一个也应该是20阿,怎么会是24呢?有明白人的给讲讲!
posted on 2005-11-11 12:56
Merlin
阅读(420)
评论(13)
编辑
收藏
收藏至365Key
所属分类:
C++
评论
#
re: 一个有意思的问题
2005-11-11 13:32
笨笨
你的程序是按照8个字节对齐的
回复
#
re: 一个有意思的问题
2005-11-11 14:00
nacci
建议你为每个类定义构造函数,然后分别生成对象后,观察每个对象的内存布局。在b中,为了和double d对齐,为c2保留了8 bytes的空间。
回复
#
re: 一个有意思的问题
2005-11-11 16:37
Merlin
为什么就char要对齐阿,而long不用对齐阿?
class b
{
char c1;
long l;
char c2;
long l1;
double d;
};//sizeof(b)=24!
这里面到底是怎么回事啊?
回复
#
re: 一个有意思的问题
2005-11-11 16:56
shootingstars
字节对齐是为了提高从内存中获取变量的效率。
如果数据总线的宽度是32位,那么每次从内存中取数据都是从4的倍数取的。如果不对齐的话,有可能取一个int型数据需要两次操作。
编译器一般都可以使用编译指令来控制是否需要字节对齐。
回复
#
re: 一个有意思的问题
2005-11-11 17:00
笨笨
如果你是VC的话,使用
#pragma pack(push,8)
#pragma pack(1)//使用一个字节对齐
你在这里写代码
#pragma pack(pop,8)
这种情况不能乱用,因为会降低效率
WINDOWS核心编程介绍字节对齐的原因
回复
#
re: 一个有意思的问题
2005-11-11 21:44
Merlin
谢谢了!
回复
#
re: 一个有意思的问题
2005-11-12 12:30
Merlin
当CPU的访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数据值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐的数据,若多次执行内存访问,应用程序的运行速度就会慢。在最好的情况下,是两倍的时间,有时更长。
-------------《Windows核心编程》
不过我还有一点不明白的:
struct s
{
char a;
long int d;
double c;
};//此时是16
struct s
{
char a;
long int d;
double c;
char a1;
};//而此时是24
也就是说a1用了8个,我觉得就没有道理啊,不是当数据大小的数据模数的内存地址是0时,数据是对齐的么? char没有必要用8个阿!有没有人明白,帮解释一下!
回复
#
re: 一个有意思的问题
2005-11-12 21:21
笨笨
哎,编译器默认是8个行不行呀?
回复
#
re: 一个有意思的问题
2005-11-12 22:49
fireup
编译器默认的对齐是8字节对齐。
两个结构在内存中的分配分别如下图
0 4 8
+-------+-------+
|char |long | 0-7
+-------+-------+
|char | 8-15
+---------------+
|double | 16-23
+---------------+
0 4 8
+-------+-------+
|c|c| |long | 0-7
+-------+-------+
|double | 8-15
+---------------+
回复
#
re: 一个有意思的问题
2005-11-13 11:10
味全每日C++
还是应该注意这一点 #pragma pack(8)
默认32位是8 ,不排除有的时候让你计算 #pragma pack(4) 的情况..
回复
#
re: 一个有意思的问题
2005-11-27 02:09
豪
学习
回复
#
re: 一个有意思的问题
2005-12-30 10:48
发
当CPU的访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数据值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐的数据,若多次执行内存访问,应用程序的运行速度就会慢。在最好的情况下,是两倍的时间,有时更长。
-------------《Windows核心编程》
不过我还有一点不明白的:
struct s
{
char a;
long int d;
double c;
};//此时是16
struct s
{
char a;
long int d;
double c;
char a1;
};//而此时是24
也就是说a1用了8个,我觉得就没有道理啊,不是当数据大小的数据模数的内存地址是0时,数据是对齐的么? char没有必要用8个阿!有没有人明白,帮解释一下!
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
除了结构体内的成员变量要求对齐外,结构自身也是需要对齐的。结构体成员的对齐是用成员本身的大小和#pragma pack(push,n)中的n中较小的数对齐,例如如果成员大小为2,而你指定的对齐方式是4,则该成员按2对齐;结构本身的对其是用结构中最大成员的大小和#pragma pack(push,n)中的n较小的数对齐,例如如果结构中最大成员大小8,而你指定对齐是16,则结构本身按8对齐。
对于
struct s
{
char a;
long int d;
double c;
};//此时是16
编译器默认的一般是8字节对齐。
a大小是1,它就按1字节对齐(因为比指定的8小),存储在0偏移的地方;b大小4,它就按4字节对齐(因为比指定的8小),存在偏移4--7的位置,c大小8,它按8字节对齐,存在偏移8--15的位置。这样3个成员共占用了16字节。由于该结构最大成员c大小为8,所以结构按8字节对齐,16按8园整还是16,因此sizeof s = 16。
而对于
struct s
{
char a;
long int d;
double c;
char a1;
};//而此时是24
前3个成员和上面一样存储,即a在0位置,d在4--7位置,c在8--16位置,但a1按一字节对齐,存在偏移17位置,这样4个成员占用了17字节;整个结构还要按8对齐(因为结构最大成员c大小为8),17按8圆整后是24,因此此时sizeof s = 24。
如果你指定编译器按4字节对齐,即你在开头加上#pragma pack(push,4)
则对于前者为12,后者为16。
我用的是vc7.1。
只有注册用户
登录
后才能发表评论。
Powered by:
IT博客
Copyright © 高山流水
日历
<
2006年3月
>
日
一
二
三
四
五
六
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
公告
我爱你们.
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(29)
给我留言
查看公开留言
查看私人留言
随笔分类
(301)
IT(22)
书评(2)
原创部分(3)
外语学习(1)
学习方法(1)
工作(39)
文学(4)
社会(10)
程序语言(85)
计算机基础知识(36)
------计算机硬件------(6)
计算机网络(7)
随笔(85)
随笔档案
(299)
2010年9月 (1)
2009年6月 (1)
2009年5月 (2)
2008年11月 (1)
2008年8月 (1)
2008年3月 (1)
2008年1月 (1)
2007年12月 (2)
2007年9月 (3)
2007年8月 (1)
2007年7月 (2)
2007年6月 (3)
2007年4月 (2)
2007年3月 (9)
2007年1月 (3)
2006年10月 (3)
2006年7月 (2)
2006年6月 (13)
2006年5月 (10)
2006年4月 (22)
2006年3月 (200)
2006年1月 (5)
2005年12月 (6)
2005年11月 (5)
相册
blog pp
test
我的相片
收藏夹
私人收藏
技术与学术blog
孙鑫VC++讲座笔记(hbyufan的专栏作品)
学习vc很有用的文章,另外vc++技术内幕的笔记也非常好。
朋友的blog
CHJ的blog
呵呵
搜索
积分与排名
积分 - 167986
排名 - 37
最新评论
1. re: 周期[未登录]
你这个傻逼连谢军都崇拜,扯那么多蛋忽悠人干啥?
--Hi
2. re: 时间和日历类的设计(Java的Date和Calendar的C++实现) (转)
我也正想自己设计这样一个类,C++的时间类太麻烦,太不灵活了。
--luoweifu
3. re: 数据结构学习笔记(转载)[未登录]
很好
--gg
4. re: 数据结构学习笔记(转载)
我需要
--微笑
5. re: BEST IS YET TO COME 歌词挺好(合金装备的尾声)[未登录]
太感谢了,终于找到它了。
玩到MSG4的最后一个Act在雪地里突然放这首歌真的差点哭了……
--francis
阅读排行榜
1. 上海KTV不完全手册(11901)
2. 数据结构学习笔记(转载)(10611)
3. 中病毒后不能/无法显示隐藏文件怎么办(6047)
4. 使用 FindBugs 的原因和方法 (5310)
5. WinCVS操作手册(5246)
6. Hash join算法原理(4091)
7. C++的类型萃取技术(3520)
8. 维生素B族的作用- -(3371)
9. 日本模型网站(zz)(3159)
10. 电容的特性(隔直通交)(3158)
11. [编程宝典]C#开发短信的方法和简介 (2916)
12. 收集的一些google搜索引擎技巧和大家分享 (2527)
13. 再谈从vc6迁移到vs2005 (转)(2395)
14. 单位转换探讨(2252)
15. 英文名字释义(2128)
16. 《c++学习笔记》转载,其余的请查看http://blog.csdn.net/hbyufan/(2016)
17. O-ZONE的Despre Tine,MP3下载,在线收听,歌词,图片(1950)
18. BEST IS YET TO COME 歌词挺好(合金装备的尾声)(1941)
19. 寻找理想“心灵感应法”和价值观"报纸测试法"-李开复(1783)
20. 三俗歌曲(1663)
评论排行榜
1. 中病毒后不能/无法显示隐藏文件怎么办(16)
2. 使用 FindBugs 的原因和方法 (8)
3. 大数运算全部源代码 (7)
4. [编程宝典]C#开发短信的方法和简介 (7)
5. 维生素B族的作用- -(5)