C++ std::copy:复制仅在1字节内发生,而不是在指定的长度内发生
请参阅下面的代码片段:C++ std::copy:复制仅在1字节内发生,而不是在指定的长度内发生,c++,C++,请参阅下面的代码片段: #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 <
#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;
}
#包括
使用名称空间std;
int main()
{
uint32_t len,x;
字符abc[]=“12345678”;
uint8_t*ptr=(uint8_t*)abc;
复印件(ptr、ptr+4、重新解释铸件(&len));
cout您的目标是长度为1的“容器”(即单个对象,len
)
您正在将四个后续字节值复制到此容器中,这当然会失败——特别是,它会导致溢出,因为目标只有一个元素的空间
代码中的其他错误(不是详尽的列表):
- 您混淆了字符代码及其字符串表示形式
- 您正在执行冗余强制转换
第一点特别重要,因为您实际上要做的是将字符串前四个字符中编码的数字解析为十进制数,但实际上要做的是复制其字符代码
在C++中解析一个数,使用AS或,因为C++ 11,
首先,<代码> STD::复制< /C> >大致如下:
template <typename InputItr, typename OutputItr>
void copy(InputItr begin, InputItr end, OutputItr obegin)
{
while (begin != end)
*obegin++ = *begin++;
}
模板
无效副本(输入开始、输入结束、输出结束)
{
while(开始!=结束)
*obegin++=*开始++;
}
您的输出迭代器是uint32\u t*
,这实际上会导致您覆盖4个32位字!(缓冲区溢出)。您看到49
,因为复制的第一个字符('1'
)具有ASCII值49。std:copy无法按预期工作。它会将源“按元素”复制到目标。因此,它会将第一个uint8(=char'1'==0x49 in hex)复制到“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;
int main()
{
uint32_t len[4];
字符abc[]=“12345678”;
副本(abc、&abc[4]、&len[0]);
你在把一个字符串一个字节一个字节地复制成一个整数,但你却对它不起作用感到困惑?为什么不使用一个可读且有效的字符串->整数转换呢?这只是一个例子。我实际上需要它在实际的代码中这样做,'1'!=1
等等。这就是你所期望的。49是ASCII r吗E字符“1”的表示。您正在将字符复制为整数。除非您知道自己在做什么,否则不要混合字符。@chris是的,从C++11开始。但值得添加。现在已经过了2012年的一半。距离2011版稳定下来还有多少年了?:/@chris如果决定是由我做出的-立即。但不幸的是,它不是这样工作的。但是是的,我同意这样的观点,我们应该在这里假设C++11。@克里斯:我不能告诉你其他任何地方,但我在哪里工作,哪里有真正的可移植代码,必须用VS(2005年以后)、g++(4.1以后)编译,Solaris CC,IBM xlCr,HPUX aCC…可能需要几年时间,也许等到我们得到一个新的标准时。@Konrad,实际上有符合标准的编译器可用吗?