【问题标题】:Copying an integer to a Buffer memcpy C++将整数复制到缓冲区 memcpy C++
【发布时间】:2009-05-28 23:11:20
【问题描述】:

基本上我想将指针的地址存储在缓冲区中。不要问我为什么

char * buff = "myBuff";
char * myData = (char*)malloc(sizeof(char*));
int addressOfArgTwo = (unsigned int)buff;
memcpy(myData, &addressOfArgTwo, sizeof(char*));

cout << "Int Val: " << addressOfArgTwo << endl;
cout << "Address in buffer:" << (unsigned int)*myData << endl;

我不明白为什么上面的代码不起作用。它输出:

Int Val: 4472832
Address in buffer:0

当 Buffer 中的 Int Val 和 Address 应该相同时。谢谢

【问题讨论】:

  • 感谢大家的帮助

标签: c++ pointers


【解决方案1】:

您取消引用 char *,生成 char,然后将该 1 字节 char 转换为 int,而不是整个 4 字节地址(如果这是 32 位机器,64 位上为 8 字节) . 4472832 是十六进制的 444000。在 little-endian 机器上,你抓取最后的 00。

*((unsigned int*)myData)

应该会显示正确的数字。

【讨论】:

    【解决方案2】:

    这通常很危险:

     *((unsigned int*)myData)
    

    Intel IA-32(每个人都习惯)支持非对齐访问,但其他一些架构不支持。它们要求变量对齐(1 字节边界上的 8 位数据、2 字节边界上的 16 位数据和 4 字节边界上的 32 位数据)。在需要对齐的架构上,未对齐的访问将返回损坏的数据或引发 CPU 异常。我在过去的工作中看到它在现实生活中导致了一个错误,一个微妙的错误导致文件系统损坏,因为我们使用的软件包附带的磁盘驱动程序(在嵌入式平台上)。

    在这种孤立的情况下,您可以看到 myData 的地址来自 malloc(),这应该意味着它适合所有类型的指针对齐,但是如果您不这样做,将较小的指针转换为较大的指针通常是一种危险的做法'不知道指针是从哪里来的。

    从任意内存位置提取 32 位整数的安全方法是声明一个临时 32 位整数并对其执行复制,将源内存视为原始字符数组:

    unsigned int GetUnalignedLittleEndianUInt32(void *address)
    {
        unsigned char *uc_address = (unsigned char *)address;
        return (
            (uc_address[3] << 24) |
            (uc_address[2] << 16) |
            (uc_address[1] << 8) |
            uc_address[0]
        );
    }
    

    或更一般地说(有一些函数调用开销):

    unsigned int GetUnalignedUInt32(void *address)
    {
        unsigned int value;
        memcpy(&value, address, sizeof(value));
        return value;
    }
    

    这实际上与你最初为获取指针所做的 memcpy() 操作相反。

    虽然,将指针视为 int:

    int addressOfArgTwo = (unsigned int)buff;
    

    正如迈克尔指出的那样,如果您在 32 位和 64 位架构之间移动,这也是危险的。指针并不总是 32 位整数。考虑使用稍后可以更改的 typedef。 Linux 上的约定是指针与 long 大小相同。在 Windows 上,有类型定义 INT_PTR、UINT_PTR、LONG_PTR 和 ULONG_PTR。

    所以,我最后建议(无论如何在 Windows 上):

    ULONG_PTR GetAddressAtAddress(void *address)
    {
        ULONG_PTR value;
        memcpy(&value, address, sizeof(value));
        return value;
    }
    

    【讨论】:

      【解决方案3】:

      正如迈克尔所说,这条线应该是

      cout << "Address in buffer:" << *((unsigned int*)myData) << endl
      

      【讨论】:

        【解决方案4】:

        代替:

        (int)*myData 
        

        应该是:

        *((int*)myData)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多