免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 7967 | 回复: 31
打印 上一主题 下一主题

关于内存对齐,结构判断偏移量 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-16 20:41 |只看该作者 |倒序浏览
最近刚好搞了个内存对齐的东东,将经验拿来大家共享,不足之处请不吝砸砖
首先我们要明白一件事情,任何变量在内存中都有地址,而处理器是有位数的,例如32位,64位,意思就是说处理器一次处理32bit(4bytes)或者64bit(8bytes)。下面以32位为例:
对于0开始的2个bytes,可以一次取出来,但是对于3开始的2个B,就要两次才能取出来,因为0-3取一次,4-7取第二次,所以需要两次。为了提高效率,我们希望将这两个字节放在能一次取出来的地方,就是4-5这两个B上。所以,内存对齐就是尽量将变量的首地址放在能一次取出的地址上。这也就是我们的结构体长度往往超过所有变量长度的和的原因。其实你申明如下变量(顺序有关)
struct{
char a;
int b;
short c;
long d;
};
再分别将他们的地址打印出来看看,不是连续分配的,内存对齐很神奇吧。
那么我们怎么判断变量首地址被分配到哪里去了呢?(内存对齐是怎么实现的)
其实很简单,你必须明白以下规则
1.系统对齐长度LO:32位机默认为4字节,程序中可以用#pragma pack(2)将其改为2,只能是2^n,不能大于4。大了不起作用。
2.你的变量长度LV,基本变量,包括(singed/unsigned)char, short,int,long,float,double,字符串变量不会对内存对齐产生影响。
3.当前可用地址之后第一个能整除MIN(LO,LV)的地址就是内存对齐之后的地址。
另外,内存对齐是编译器相关的,不同的编译器可能有细微的差别,但总体遵循以上原则。
这是我的函数
/*************************************
* 根据当前地址和数据类型判断是否需要对齐
* 如果需要对齐,返回下一个变量可用地址
* p 内存当前地址
* len 需对齐的变量长度, 只能是简单变量
* 例如        char         1
*             short        2
*             int          4
*             long         4
*             float        4
*             double       8
* 返回值,对齐后的地址
*************************************/
void * getMemAddr( void * p, unsigned short len )
{
    len = MIN( len, PACK_LEN );

    if( p == NULL ) return NULL;
    if( (unsigned int)p%len != 0 )
    {
        return p+len-(unsigned int)p%len;
    }
    else
        return p;
}


PACK_LEN就是LO,此处定义为4,32位机的

[ 本帖最后由 blackuhlan 于 2008-7-18 07:11 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-07-17 00:05 |只看该作者
怎么老有人去研究结构对齐这东西, 实际什么益处

论坛徽章:
0
3 [报告]
发表于 2008-07-17 00:13 |只看该作者
实际作用就是:封装了个数据库查询函数出来

论坛徽章:
0
4 [报告]
发表于 2008-07-17 00:14 |只看该作者
底层来讲的话, 对齐是很重要的哦

论坛徽章:
0
5 [报告]
发表于 2008-07-17 00:21 |只看该作者

回复 #2 mik 的帖子

这是一个学习过程吧,人喜欢钻研是一件好事,只要能够认清自己在做什么即可

论坛徽章:
0
6 [报告]
发表于 2008-07-17 00:34 |只看该作者
原帖由 mik 于 2008-7-17 00:05 发表
怎么老有人去研究结构对齐这东西, 实际什么益处


对设计mmu的人有益处

论坛徽章:
0
7 [报告]
发表于 2008-07-17 00:58 |只看该作者
原帖由 blizzard213 于 2008-7-17 00:34 发表


对设计mmu的人有益处

压根跟mmu沾不上边

论坛徽章:
0
8 [报告]
发表于 2008-07-17 01:36 |只看该作者
up一下 一直对这个不太理解
试了一下 ...还是不理解
---------------------------
3.当前可用地址之后第一个能整除MIN(LO,LV)的地址就是内存对齐之后的地址。//这个好象不大对劲吧,能用个例子解释下么?

论坛徽章:
0
9 [报告]
发表于 2008-07-17 10:11 |只看该作者
原帖由 mik 于 2008-7-17 00:05 发表
怎么老有人去研究结构对齐这东西, 实际什么益处

哈哈,这是个学习的过程哈,自己通过思考实践搞懂一个问题后,总想跟大家分享一下经验。虽然对其它人来说可能早就知道了。
总之比不搜索、不思考,直接发月经贴问好多了

论坛徽章:
0
10 [报告]
发表于 2008-07-17 10:50 |只看该作者
为什么没有实际用处,等你遇到问题就知道有用处了,俺就遇到过好几次鸟,老是不吸取教训
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP