关于结构体类型数据的强制类型转换

zzjb 2005-09-15 08:33:39
有如下结构体定义:
typedef struct cemsg
{
uchar dl;
uchar mg;
uchar data[10];
}CEMSG;

typedef struct msg{
uchar id;
uchar cmd;
uchar byte[4];
}MSG;

typedef struct msg_p{
uchar id;
uchar cmd;
uchar far * ptr;
}MSG_P;

void ap_getmsg(MSG *d_OsMsgPtr,CEMSG *d_CeMsgPtr)
{
MSG_P *d_p;
d_p = ( MSG_P * )d_OsMsgPtr;
cpy( d_CeMsgPtr, d_p->ptr, ( ushort )(( CEMSG far* )d_p->ptr )->dl + 1 );
}

注:其中cpy(dest,src,n)函数的功能是把src开始的n byte数据copy到dest开始的数据区域内。

在仿真调试中:
程序进入函数时,d_OsMsgPtr的个数据项地址及值如下:
地址d_OsMsgPtr---0x00ffb21c ; d_OsMsgPtr->byte[4]---0x00ffb21e
值d_OsMsgPtr->id==0x0c;d_OsMsgPtr->cmd == 0x11; d_OsMsgPtr->byte[0]==0xD4;d_OsMsgPtr->byte[1]==0xD0;d_OsMsgPtr->byte[2]==0xFF;d_OsMsgPtr->byte[3]==0x00;

当函数执行完d_p = ( MSG_P * )d_OsMsgPtr;这句时:
地址d_p---0x00ffb21c ; d_p->ptr---0x00ffD0D4
值d_p->id==0x0c;d_p->cmd == 0x11; *d_p->ptr==0x06;

q
...全文
977 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
goodluckyxl 2005-09-16
  • 打赏
  • 举报
回复
从代码来看
typedef struct msg{
ucharid;
ucharcmd;
ucharbyte[4];
}MSG;
这个结构中的 byte[4]中存放的是一个CEMSG变量的地址
typedef struct cemsg
{
uchar dl; //应该意思为data length 数据体的长度
uchar mg;
uchar data[10];
}CEMSG;
ap_getmsg(MSG *d_OsMsgPtr,CEMSG *d_CeMsgPtr)
的意思就是将 d_OsMsgPtr指针强制转化为MSG_P*
也就是byte[4]中存放的 CEMSG对象的地址赋给ptr
然后进行结构拷贝 拷贝长度为dl + 1这个1应该为其本身dl占的一个uchar


xiaocai0001 2005-09-16
  • 打赏
  • 举报
回复
0x06是不是结构体msg_p的长度呢?存放在地址0x00ffD0D4中?
-----------------------
与结构体长度无关,实际上,你幸好没有做*d_p->ptr = ***(赋值)操作
否则,将对0x00ffD0D4地址的内容进行操作,这并不是合法的操作.

( CEMSG far* )d_p->ptr 这句,CEMSG是一个结构体类型,d_p->ptr是一个指向一个数组的地址类型,并且是一个结构体的数据项(并不是一个结构体),这样的类型转换,可以强制转化吗?又是如何操作的呢?
-------------
首先d_p->ptr 所指向的地址并不是你预想中所指的地址,所以对它进行强制类型转换,结果未知.(绝对是不安全的)
zzjb 2005-09-16
  • 打赏
  • 举报
回复
谢谢!再问:
1.0x06是不是结构体msg_p的长度呢?存放在地址0x00ffD0D4中?
2.:( CEMSG far* )d_p->ptr 这句,CEMSG是一个结构体类型,d_p->ptr是一个指向一个数组的地址类型,并且是一个结构体的数据项(并不是一个结构体),这样的类型转换,可以强制转化吗?又是如何操作的呢?
xiaocai0001 2005-09-15
  • 打赏
  • 举报
回复
注意强制转换后,是用新的结构体来解析原来空间的内容

所以强制转换后的结构体内的指针把原来空间的内容当作自己的内容,而不是指向原来空间的地址

所以&(d_p->ptr)才是d_OsMsgPtr->byte的首地址
同样在进行( CEMSG far* )d_p->ptr 转换后
&(d_p->ptr)才是uchar data[10];的首地址

而且有一个问题,结构体的长度不一致,进行强制类型转换后,可能出现内存访问越界


xiaocai0001 2005-09-15
  • 打赏
  • 举报
回复
但是为什么*d_p->ptr的值不是d_OsMsgPtr->byte[0],0x06又是从何而来呢?
----------------
由于d_p->ptr内存放的值是0x00ffD0D4,所以
*d_p->ptr的值实际上是内存中(0x00ffD0D4)单元中存放的内容

xiaocai0001 2005-09-15
  • 打赏
  • 举报
回复
d_p的地址为d_OsMsgPtr的0x00ffb21c,d_p->ptr的地址却不是d_OsMsgPtr->byte[4]的地址。
--------------------
指针强制类型转换实际上就是用新的指针类型来解析原来地址空间中的内容

比如d_OsMsgPtr原来空间的内容是
(struct msg_p)
1byte 1byte 4bytes
id cmd byte[4]

强制类型转换之后,就要以struct msg_p来解析该内容
一共6bytes
1byte 1byte 4bytes
id cmd ptr
原来byte[4]的内容成为ptr的内容,而不是byte[4]的首地址.

zzjb 2005-09-15
  • 打赏
  • 举报
回复
请问:
1:在对d_OsMsgPtr强制转换为MSG_P类型时,具体的执行过程时怎样的,为什么转换之后,d_p的地址为d_OsMsgPtr的0x00ffb21c,d_p->ptr的地址却不是d_OsMsgPtr->byte[4]的地址。
2:转换完毕之后,d_p->ptr应该是指向d_OsMsgPtr->byte的指针,但是为什么*d_p->ptr的值不是d_OsMsgPtr->byte[0],0x06又是从何而来呢?
3:( CEMSG far* )d_p->ptr 这句,CEMSG是一个结构体类型,d_p->ptr是一个指向一个数组的指针类型,并且是一个结构体的数据项,这样的类型转换,又是如何操作的呢?

请各位多多指教,谢了!

69,371

社区成员

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

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