如何在不破坏堆栈的情况下设置此结构?

时间:2012-11-21 11:06:28

标签: c

我需要设置以下结构并打印出addr-array的内容。

typedef struct
{
    uint8                   len;
    uint8                   ch;
    uint8                   cmd;
} ATTR_PACKED
RESPONSE_R;

typedef struct
{
    RESPONSE_R          rspr;
    uint8               addr[SIZEOF_ADDR];
} ATTR_PACKED
RESPONSE_ADDR;

但是,我目前的解决方案是在变量rspr周围破坏我的堆栈。据我所知,这是因为addr是一个数组,我设置错了。但我不确定是否如此以及为什么。在调试器上它看起来没问题,直到我在退出函数时收到错误消息。

//this code has to be ansi-c
void    OnResponse(uint8 *pPkt){

RESPONSE_R rspr;
//pPkt[0] holds the lenght of the received response, which equals to sizeof(rspadr)
//before this was ok, but I guess, now it is not, because RESPONSE_R stores just the
//pointer, not the whole array
memcpy(&rspr,pPkt,pPkt[0]-sizeof(rspr));            

switch(rspr.cmd){
 case CMD_READ_ADDR:
   RESPONSE_ADDR rspadr;
   memcpy(&rspadr,pPkt,pPkt[0]);
   //nevermind the cout, this is for debug only     
   cout << "ADDR: " << endl;                
   printf("%02x",rspadr.addr[0]);
   break;
 default:
   break;
 }
}

rspadr获取正确的数据,为什么我会使用此代码破坏我的堆栈?

修改

memcpy使用pPkt来确定大小,因为pPkt[0]包含传输的响应字节的大小。但也许这里有一点,我应该改变它直接使用结构大小。但是 - 这不是主要问题。

主要的麻烦制造者是,当其中一个结构有数组时,如何将pPkt[]缓冲区中的数据转换为我的结构,就像RESPONSE_ADDR一样?

pPkt[128]数组的原始视图

[0x0] = 0x09
[0x1] = 0x00
[0x2] = 0x02
[0x3] = 0x00
[0x4] = 0x16
[0x5] = 0x01
[0x6] = 0x02
[0x7] = 0x03
[0x8] = 0x04

[0xa] = 0x00
[0xb] = 0x00
[0xc] = 0x00
...
[0x127] = 0x00

以上是我得到的输入。现在,我需要设置一个RESPONSE_R对象,以便选择由cmd部分(由pPkt [2]表示)和RESPONSE_ADDR对象确定的rountine,以便获得地址,即001601020304

我非常希望能够使用rsp.cmdrspadr.addr[0]之类的内容。

2 个答案:

答案 0 :(得分:2)

这一行看起来很可疑:

memcpy(&rspr,pPkt,pPkt[0]-sizeof(rspr));  

memcpy的第三个参数是要复制的字节数,不能超过RESPONSE_R的大小。

你的意思是

memcpy(&rspr,pPkt,sizeof(rspr));  

更新2

这个解决方案怎么样,不需要任何memcpy

const RESPONSE_R* p_rspr = (const RESPONSE_R*)pPkt;

switch(p_rspr->cmd){
 case CMD_READ_ADDR:
   const uint8* addr = pPkt+sizeof(RESPONSE_R);
   //nevermind the cout, this is for debug only     
   cout << "ADDR: " << endl;    
   for (uint i = 0; i != p_rspr->len; ++i)            
     printf("%02x", addr[i]);
   break;
 default:
   break;
 }

答案 1 :(得分:2)

您能否重新检查以下声明?

RESPONSE_R rspr;
memcpy(&rspr,pPkt,pPkt[0]-sizeof(rspr));    

看起来你试图以不正确的方式复制。