【问题标题】:Using memcpy to copy arrays of different type [closed]使用 memcpy 复制不同类型的数组 [关闭]
【发布时间】:2012-10-20 11:16:04
【问题描述】:

我已经阅读了thisthisthis,但他们都没有回答我想知道的问题

从保存到原始数组 (buffer) 的硬件返回一组 PId(每个 3 个字节)。该设备准确返回 84 个字节。

然后我需要将这些 PId 复制到一个或多个数组中,该数组可由该设备的 API 库读取。

这是我的代码

#pragma pack (1)
typedef unsigned char PId[3];
typedef PId PIDs[28];

int GetList(PId* plist){

    unsigned char buffer[84];

    //... Reads the data from hardware memory to buffer
    if (RunCMD(0xCD, &buffer)){
        // buffer has the correct data now 'AAAA...'

        memcpy(&plist,buffer, 84);

        printf("%02X%02X%02X\n", buffer[0], buffert[1], buffer[2]); 
        printf("%02X%02X%02X\n", buffer[3], buffer[4], buffer[5]); 

        return 0;
    } 
    return 1;
}

int main(void) {
    ...

    PId plist_a;
    GetList(&plist_a);

    printf("%02X%02X%02X\n", plist_a[0][0], plist_a[0][1], plist_a[0][2]); 
    printf("%02X%02X%02X\n", plist_a[1][0], plist_a[1][1], plist_a[1][2]); 
    ...
}

不知何故,这段代码没有将正确的数据复制到PIDs数组。 buffer 有正确的数据,但在memcpy 之后,pids 没有相同的数据。

我知道我做错了什么,但我找不到。

如果有帮助,我将使用 windows GCCARM CPU 编译我的代码

编辑:我很抱歉让大家感到困惑,实际上代码是有效的,但是我错过了一部分代码。我更正了。 pids 不是 PIDs 类型,它是指向它的指针。

【问题讨论】:

  • 不是答案,只是一个注释。请注意,对于数组,您不需要传递地址。就做memcpy(pids, buffer, 84)
  • 那你得到什么数据?在memcpy之后比较buffer的内容和pid,看看有没有关联。您还可以在 memcpy 之前将 pid 清零,以查看具体被覆盖的内容。
  • @apalopohapa,数据根本不相关,它显示的是一组指针而不是数据。我的测试数据是 AAAA.... 但 pids 中的结果是 0x5FFE76 0x5FFE79 0x5FFE7B
  • 您是否已将硬件指针声明为易失性?如果没有,那么代码可能会被优化掉。
  • 这些结果以 3 为增量(PId 中的字节数相同),因此您以某种方式写入 PId 地址而不是其内容。您应该发布您的实际代码,因为这肯定是 c 的陷阱之一。

标签: c


【解决方案1】:

看看the answer to this question。您可能不想直接使用数组的typedefs。

试试这样的:

声明:

#pragma pack (1)

typedef struct PId
{
    unsigned char pid[3];
} PId;


typedef struct PIDs
{
    PId pids[28];
} PIDs;

那么,对于 memcpy...

其他人指出您正在传递指针,例如PId* plist,但您正在尝试使用像memcpy(&plist, buffer, 84); 这样的memcpy。 & 符号会搞砸你,因为它会引用指针本身的地址。你想要的是:

//plist should probably be a pointer to PIDs, not PId
int GetList(PIDs* plist){

    unsigned char buffer[84];

    //... Reads the data from hardware memory to buffer
    if (RunCMD(0xCD, &buffer)){
        // buffer has the correct data now 'AAAA...'

        //remove the & symbol
        memcpy(plist,buffer, 84);

    //etc
}

【讨论】:

    【解决方案2】:

    请注意,对于数组,您不需要传递地址。做吧

    memcpy(pids, buffer, 84);
    

    【讨论】:

      【解决方案3】:

      我很困惑为什么这甚至可以编译。而不是

      typedef PIDs PId[28];
      

      你需要

      typedef PId PIDs[28];
      

      使用typedef,您可以将新类型的名称放在变量通常所在的位置。

      【讨论】:

      • 抱歉打错字了,为了便于阅读,我删除了 32 个字符长的真实姓名
      【解决方案4】:

      这可能有效:

      #pragma pack (1)
      
      struct PId{
        unsigned char pid[3];
      };
      
      int main(){    
        unsigned char buffer[84];
        struct PId pids[28];
      
        /* buffer gets populated somewhere here */    
      
        memcpy(pids, buffer, 84);
      }
      

      【讨论】:

        猜你喜欢
        • 2014-04-15
        • 2014-07-31
        • 2021-04-10
        • 2015-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-13
        • 2020-04-22
        相关资源
        最近更新 更多