指针指向奇数地址的问题

daviddb7 2007-07-25 12:40:12
指向奇数地址的指针强制类型转换到short *时出现exception,非法指针。但用结构就不会。
为什么?

例如:
struct ss
{
short sss;
} __attribute__((packed));
char *pch;
short s;

pch = POSITION; //任意奇数地址,比如一个string中间
s = *(short *)pch; //这样执行就出错
s = ((struct ss *)pch)->sss; //这样就可以

为什么呢?
...全文
1201 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
taodm 2007-07-25
  • 打赏
  • 举报
回复
arm系统?arm有很多额外要求的,只好看arm的资料并照着做,没啥为什么。
daviddb7 2007-07-25
  • 打赏
  • 举报
回复
多谢各位帮忙,问题已解决,结贴。
daviddb7 2007-07-25
  • 打赏
  • 举报
回复
拼写手误,应为packed
goodluckyxl 2007-07-25
  • 打赏
  • 举报
回复
首先你需要了解这个MIPS硬件支持非对齐访问不
如果支持没有必要再深究了

如果不支持 看是否有替代的配置使其软件层面来解决奇地址访问的问题
比如像arm下packed保留字段只类

如果也没有那么看其汇编是否将奇地址的数据访问打散成字节访问形式再组装

如果不是那这个编译器是一泡屎
daviddb7 2007-07-25
  • 打赏
  • 举报
回复
多谢lddLinan(不再五行中)提醒。
刚才看过汇编了,如果直接强制类型转换,汇编当中是一条指令,直接操作一个short.
但如果用了结构,汇编当中就会拆成两次byte操作,自然不会有问题了。
而且是跟packet属性有关的。如果没有packet属性,汇编的指令和直接类型转换是一样的,直接操作short。

得出结论:在使用packet的结构当中,不管什么类型最后都是以byte方式操作的,所以不用考虑对齐的问题。
lddLinan 2007-07-25
  • 打赏
  • 举报
回复
看看汇编代码不就清楚了
daviddb7 2007-07-25
  • 打赏
  • 举报
回复
不是ARM的,是MIPS的。
ARM上访问奇数地址似乎也没有问题。不会当机,只是结果不是预期的。好像会被强制对齐。
倒是MIPS的让我碰上几次了。几种MIPS的CPU都是。

我只是想知道,pch是个奇数地址,用((struct ss *)pch)->sss的方式,sss应该还是个奇数地址啊,怎么就可以访问了呢?
goodluckyxl 2007-07-25
  • 打赏
  • 举报
回复
x86下可以使用c测试也可以嵌入汇编测试奇数地址访问
#include <stdio.h>

void main()
{
char* pstr = "123456";
short d = 0;

if((int)pstr&1)
d = *(short*)pstr;
else
d = *(short*)(pstr+1);
__asm
{
mov eax, dword ptr[pstr]
mov ax, word ptr[eax+1]
}
printf("test packed data d:=%x", d);
}
goodluckyxl 2007-07-25
  • 打赏
  • 举报
回复
short sss; 存放地址一般都是以short对齐放的地址不会奇数

x86下是虚拟地址,本身cpu也支持非对齐访问

arm需要指定__packed修饰后会使用ldrb和strb操作 就是正常了
否则arm会优化使用str ldr
星羽 2007-07-25
  • 打赏
  • 举报
回复
vc上是好的
lddLinan 2007-07-25
  • 打赏
  • 举报
回复
编译器一定对pch->ssh作了对齐处理
jixingzhong 2007-07-25
  • 打赏
  • 举报
回复
看访问的方式。

内存对齐就是为了防止类似的问题

70,014

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧