将整数复制到缓冲区 memcpy C++

Posted

技术标签:

【中文标题】将整数复制到缓冲区 memcpy C++【英文标题】:Copying an integer to a Buffer 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 应该相同时。谢谢

【问题讨论】:

感谢大家的帮助 【参考方案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)

【讨论】:

以上是关于将整数复制到缓冲区 memcpy C++的主要内容,如果未能解决你的问题,请参考以下文章

将整数转换为字符缓冲区以进行串行通信......? [关闭]

TCP memcpy 缓冲区使用 C++ 返回垃圾数据

从 C++ UDP 缓冲区接收字符串

如何提高 memcpy 的性能

memcpy 是可简单复制的类型构造还是赋值?

将字节缓冲区内容复制到结构中