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

有如下结构体定义:
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;

/*******************************************************************************************************************************************************************************/


请问:
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是一个指向一个数组的指针类型,并且是一个结构体的数据项,这样的类型转换,又是如何操作的呢?

4:0x06是不是结构体msg_p的长度呢?存放在地址0x00ffD0D4中?


答:1、指针强制类型转换实际上就是用新的指针类型来解析原来地址空间中的内容

         比如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]的首地址.


*****注意强制转换后,是用新的结构体来解析原来空间的内容

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

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

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


  2、由于d_p->ptr内存放的值是0x00ffD0D4,所以
*d_p->ptr的值实际上是内存中(0x00ffD0D4)单元中存放的内容


  3、首先d_p->ptr 所指向的地址并不是你预想中所指的地址,所以对它进行强制类型转换,结果未知.(绝对是不安全的)


  4、与结构体长度无关,实际上,你幸好没有做*d_p->ptr = ***(赋值)操作
否则,将对0x00ffD0D4地址的内容进行操作,这并不是合法的操作.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值