memcpy的怪异行为

问题描述

我想逐字节将无符号长整数复制到char缓冲区。 如果我使用注释下的行,则该行不会复制到缓冲区。

    char buf[128];
    //unsigned long int_val = 268435456;
    unsigned long int_val = 293456376;

    cout << "Value of int_val: " << int_val << endl;

    memset(buf,sizeof(buf));

    memcpy(buf,&int_val,sizeof(long));
    cout << "Value after unsigned long int copy - buf: " << buf << endl;

    const int len = strlen(buf);
    cout << "buf" << endl << "====" << endl;
    for (int i = 0; i < len; i++)
    {
        printf("%3d (0x%02X)\n",buf[i],buf[i]);
    }

以下是每个值的两次运行的输出

Value of int_val: 268435456
Value after unsigned long int copy - buf:
buf
===

Value of int_val: 293456376
Value after unsigned long int copy - buf: ��}
buf
===
 -8 (0xFFFFFFF8)
-55 (0xFFFFFFC9)
125 (0x7D)
 17 (0x11)

解决方法

它不会复制到缓冲区。

是的。

cout << ... << buf << endl;
const int len = strlen(buf);

目前还不清楚为什么您没有期望看到的输出。 0是空终止符的值。如果整数的最低存储顺序字节为0,则缓冲区包含以空值终止的字符串,该字符串表示空字符串。在这种情况下,您将看到预期的输出。在小型字节序系统上(以及在long大于4个字节的大型字节序系统上),268435456碰巧是十六进制的0x10'00'00'00。

仅因为您复制的字节代表空字符串,并不意味着未复制字节。

,

以十六进制表示的268435456为10000000 16 。您的C ++将unsigned long的字节存储在内存中,而低值字节则存储在内存中的较早位置,因此它以值00 16 ,00 16 ,00 16 ,10 16

memcpy正确地将这些字节复制到buf中。

然后,当strlen(buf)检查buf时,它将首先找到一个空字节(00 16 )。这表明buf中的字符串的长度为零,因为终止字符立即出现在开头。因此strlen(buf)返回零。

由于此返回值已分配给len,因此循环for (int i = 0; i < len; i++)执行零次迭代。

类似地,在cout << "Value after unsigned long int copy - buf: " << buf << endl;中,buf包含一个长度为零的字符串,因此没有打印任何字符。