【问题标题】:weird behaviour of memcpymemcpy 的奇怪行为
【发布时间】:2020-10-26 10:21:33
【问题描述】:

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

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

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

    memset(buf, 0, 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)

【问题讨论】:

  • 充满随机字节的缓冲区不是字符串,不能在其上使用strlen,也不能打印。此外,最好避免混合 stdio 和 iostream,即使只是为了美观。
  • 您将buf 视为在多个位置以空字符结尾的字节字符串,但事实并非如此。
  • 您希望得到什么输出?你知道打印char 指针的作用吗?
  • 你忘了在你的问题中提到你觉得奇怪的是什么。你期望结果是什么?

标签: c++ memcpy


【解决方案1】:

它没有被复制到缓冲区。

是的。

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

不清楚为什么您没有预料到您看到的输出。 0 是空终止符的值。如果整数的最低内存顺序字节为 0,则缓冲区包含表示空字符串的以空字符结尾的字符串。在这种情况下,您看到的输出是可以预期的。在小端系统(以及long 大于 4 个字节的大端系统上)恰好是 268435456 的情况,即 0x10'00'00'00 十六进制。

仅仅因为您复制的字节代表空字符串,并不意味着这些字节没有被复制。

【讨论】:

    【解决方案2】:

    在十六进制中,268435456 是 1000000016。您的 C++ 将 unsigned long 的字节与内存中较早的低值字节一起存储在内存中,因此它作为字节存储在内存中,值为 0016、0016, 0016, 1016.

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

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

    由于这个返回值被赋值给len,循环for (int i = 0; i &lt; len; i++)执行零次迭代。

    同样,在cout &lt;&lt; "Value after unsigned long int copy - buf: " &lt;&lt; buf &lt;&lt; endl; 中,buf 包含一个长度为零的字符串,因此不会为其打印任何字符。

    【讨论】:

      猜你喜欢
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      相关资源
      最近更新 更多