std::copy :复制只发生在 1 个字节,而不是指定的长度

std::copy : copy is happening only for 1 byte and not for specified length

本文关键字:复制 copy std 字节      更新时间:2023-10-16

请参阅下面的代码片段:

#include <iostream>
using namespace std;
int main()
{
uint32_t len, x;
char abc[] = "12345678";
uint8_t *ptr = (uint8_t *)abc;
copy(ptr, ptr + 4, reinterpret_cast<uint32_t*>(&len));
cout << " len: " << len << endl;
} 

输出为 49!我希望输出为 1234。我错过了什么吗

您的目标是长度为 1 的"容器"(即单个对象,len )。

您将四个后续字节值复制到此容器中,这当然会失败 - 特别是,它会导致溢出,因为目标只有单个元素的空间。

代码中的其他错误(并非详尽列表):

  • 您混淆了字符代码及其字符串表示形式
  • 您正在执行冗余转换

特别是第一点是相关的,因为您实际想要做的是将字符串前四个字符中编码的数字解析为十进制数。但你实际做的是复制它的字符代码。

要解析 C++ 中的数字,请使用 std::stringstream 或自 C++11 起std::stoi

std:copy 无法按预期工作。它将源"按元素"复制到目标。因此,它将第一个 uint8(= char '1' == 十六进制中的 0x49)复制到 'len',然后继续践踏内存中的三个随机 uint32 值。

这是为了看看实际发生了什么。

#include <iostream>
using namespace std;
int main()
{
  uint32_t len[4];
  char abc[] = "12345678";
  copy(abc, &abc[4], &len[0]);
  cout << " len: " << len[0] << " " <<len[1] << " " << len[2] << " " << len[3] << endl;
} 

首先,std::copy大致这样做:

template <typename InputItr, typename OutputItr>
void copy(InputItr begin, InputItr end, OutputItr obegin)
{
    while (begin != end)
        *obegin++ = *begin++;
}

您的输出迭代器是 uint32_t* ,这实际上会导致您覆盖 4 个 32 位字!(缓冲区溢出)。您看到49因为复制的第一个字符 ( '1') 的 ASCII 值为 49。