免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: dynamic516
打印 上一主题 下一主题

[C] 指针类型强转时,奇数地址会产生问题,为什么?[赋详细数据] [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-04-15 17:40 |只看该作者
字节对齐在16位的8086时就已经存在。你如果读偶地址上的一个字,CPU只读一次;如果读奇地址上的字,譬如读FFF1-FFF2里的字,它是先读FFF0-FFF1,再读FFF2-FFF3,然后各取一字节拼成一字。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
12 [报告]
发表于 2009-04-15 18:52 |只看该作者
原帖由 dynamic516 于 2009-4-15 14:13 发表
指针类型强转时,奇数地址会产生问题,为什么


但是楼主给出的有问题的地址都是偶数, 奇数反而没问题。 是否是楼主恰好写反了?


楼主试试如下办法:

对可能发生未对齐的读访问:
unsigned int u = *(unsigned int*) ptr;

改为 :
unsigned int u;
memcpy(&i, ptr, sizeof(u) );


同理, 对可能发生未对齐的写访问:
unsigned int u = 1212;
*(unsigned int*) ptr = u;

改为:
unsigned int u = 1212;
memcpy(ptr, &u, sizeof(u) ); /* 需要注意是否溢出ptr的范围。 */

[ 本帖最后由 OwnWaterloo 于 2009-4-15 18:55 编辑 ]

论坛徽章:
3
天蝎座
日期:2014-10-25 13:44:312015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:48:31
13 [报告]
发表于 2009-04-15 22:34 |只看该作者
原帖由 dynamic516 于 2009-4-15 14:13 发表
指针类型强转时,奇数地址会产生问题,为什么?[赋详细数据]

/* 要求必须使用(unsigned int *)p来访问,list的类型定义也不能改*/
unsigned int *p1 = NULL;
unsigned int *p2 = NULL;

/*下面访问p2或li ...


先把环境说一下吧,什么机器,什么CPU,什么编译器?

记得以前有个 老会员 一个帖, 好像是SUN的SPARC机器,访问long,需要从XX地址开始(好像和奇偶地址有关),否则程序会core掉?

[ 本帖最后由 ilex 于 2009-4-15 22:39 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2009-04-15 22:40 |只看该作者
1字节对齐结果如何?

论坛徽章:
0
15 [报告]
发表于 2009-04-16 10:00 |只看该作者

回复 #1 dynamic516 的帖子

总线寻址问题,即使一字节对齐也没用。
关键就是奇地址强制转换造成的。
在arm与sparc这些效率优先的系统都会这样。
避免的方法可以用memcpy代替强制转换。

论坛徽章:
0
16 [报告]
发表于 2009-04-16 10:41 |只看该作者
原帖由 urapple 于 2009-4-16 10:00 发表
总线寻址问题,即使一字节对齐也没用。
关键就是奇地址强制转换造成的。
在arm与sparc这些效率优先的系统都会这样。
避免的方法可以用memcpy代替强制转换。


可以解释下吗?

论坛徽章:
0
17 [报告]
发表于 2009-04-16 12:51 |只看该作者

回复 #15 urapple 的帖子

我用的平台确实是arm7的cpu ,编译器是ads1.2 。

论坛徽章:
0
18 [报告]
发表于 2009-04-16 13:00 |只看该作者
原帖由 qsc555 于 2009-4-16 10:41 发表


可以解释下吗?



也想请urapple讲解下具体原因,问题就出在强转时,可强转后访问这个地址输出的数据是对的呀
是直接把这个地址中的数据写到文件中去的比对的。
还是没弄明白这个强转到底导致了什么错误使运行时结果不对。
如果说读的是偶数地址,然后再拼成最后的数据,那也不会运行时出错呀?

论坛徽章:
0
19 [报告]
发表于 2009-04-16 14:20 |只看该作者
原帖由 dynamic516 于 2009-4-15 14:13 发表
指针类型强转时,奇数地址会产生问题,为什么?[赋详细数据]

/* 要求必须使用(unsigned int *)p来访问,list的类型定义也不能改*/
unsigned int *p1 = NULL;
unsigned int *p2 = NULL;

/*下面访问p2或li ...


To Lz:
这类问题的结果和CPU的体系结构有关,取决于CPU寻址的时候能否自动处理不对齐的情况。下面这个小程序是一个例子。
分别在Sparc(solaris+CC)和x86(vc6.0)上面测试: Sparc上面就会崩溃(Bus error (core dumped)),x86就没有问题,试一下吧

#include<stdio.h>
int main(void){
char buf[8]={'a','b','c','d','e','f'};
char *pb=&(buf[1]);
int *pi=(int*)pb;
printf("%d\n",*pi);
return 0;
}

论坛徽章:
0
20 [报告]
发表于 2009-04-16 14:32 |只看该作者
原帖由 jeanlove 于 2009-4-16 14:20 发表


To Lz:
这类问题的结果和CPU的体系结构有关,取决于CPU寻址的时候能否自动处理不对齐的情况。下面这个小程序是一个例子。
分别在Sparc(solaris+CC)和x86(vc6.0)上面测试: Sparc上面就会崩溃(Bus error (c ...


Plus: 在hp的pa-risc(aCC),itanium(aCC),IBM(xlC)的power上面测试
power不会core dump, pa-risc和Itanium也均core dump.

[ 本帖最后由 jeanlove 于 2009-4-16 14:44 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP