我可以使用STD ::复制将数据的位模式从整数向量复制到一系列未签名的字符
Can I use std::copy to copy bit pattern of data from vector of integers to an array of unsigned char
最近我一直在尝试更新一些代码以利用标准的C 库功能,而不是旧的C样式函数。特别是,我尝试做以下(为简单起见的人为工作示例 - 我知道代码很丑陋,但它简单地说明了问题):
std::vector<int> vData;
vData.push_back(10990);
vData.push_back(11990);
vData.push_back(12990);
vData.push_back(13990);
unsigned char szBuffer[100];
memset(szBuffer,0,sizeof(szBuffer));
std::copy(vData.begin(),vData.end(),szBuffer);
我期望这将以与我要替换的代码相似的方式行为:
memcpy(szBuffer,&vData[0],sizeof(int)*vData.size());
但要调试代码,很明显,我编写的std::copy
代码仅写入unsigned char
缓冲区的前4个字节,而不是向量中4个整数的完整位模式。有人可以告诉我我做错了什么,还是简单地说我不能以这种方式使用std::copy
并且应该坚持使用memcpy
?
坚持使用memcpy
,std::copy
是智能的,它了解涉及的类型,并使用标准转换正确地将int
转换为unsigned char
。memcpy
是无知的,这就是您想要的。
我期望这将以与我要替换的代码相似的方式行为...
书面的std::copy
不能以与std::memcpy
或std::memmove
相似的方式行为,因为std::vector<int>
的元素与unsigned char szBuffer[100]
的元素之间的类型不匹配。克服这种类型不匹配的一种方法是将szBuffer
投射到int*
:
std::copy(vData.begin(),vData.end(),reinterpret_cast<int*>(szBuffer));
reinterpret_cast
是个人喜好问题。我宁愿看到一些尖叫的东西"危险,危险,鲁滨逊!"对于可以在隐藏但不会消除UB潜力的C风格的铸件上调用不确定行为的事物。我(和我的项目经理霸主)可以为reinterpret_cast
。
UB的潜力是真实的,因为不能保证由于对齐问题而有效。
还请注意,不能保证std::copy
将永远通过memcpy
或memmove
实现。标准中没有一个单词(2003年或2011年)说std::copy
需要通过memcpy
或memmove
实现。(顺便说一句:在我看到的每个实施中,std::copy
都将通过std::memmove
实施,如果这样做的话,就好像"使用了"幼稚的实现"一样。)
从std::memcpy
切换到std::copy
的唯一原因是美学。有时美学会阻碍。"愚蠢的一致性是小小的妖精。"我建议坚持使用std::memcpy
。它完全可以做您想要的,并且此用法是安全的,因为没有重叠,并且由于缓冲区的尺寸适当。
,因为标准是行为(如果不是确切的实现) std::copy
等于:
namespace std {
template< typename InIter, typename OutIter >
OutIter std::copy( InIter begin, InIter end, OutIter outp )
{
for( ; begin != end; ++begin, ++outp )
{
*outp = *begin;
}
return outp;
}
}
这意味着它会逐元复制成员,递增每个迭代器并返回输出中的下一个写入位置。
这与Memcpy不同,这是您在这里真正想要的。使用memcpy没有错(即使某个Microsoft编译器告诉您它是不安全的,它可能是,但是如果您不正确驾驶卡车,那就驾驶卡车,这并不意味着没有人可以开车一个)。
将向量的内容解释为原始内存,将 reinterpret_cast
使用至 unsigned char *
:
std::copy(reinterpret_cast<unsigned char *>(&*vData.begin()),
reinterpret_cast<unsigned char *>(&*vData.end()), szBuffer);
您需要间接并取下开始和结束元素的地址,因为不能保证vector::iterator
是一种指针类型。
这是reinterpret_cast
的少数保证安全用途之一。
- 在这种情况下,我真的复制了字节还是复制了字符?
- 如何返回/复制unique_ptr<无符号字符[]>的值?
- 使用动态分配将 char* 复制到另一个字符**
- 库达如何将字符**从内核复制到主机
- 将字符向量复制到另一个向量
- 为什么我的代码在尝试复制字符数组时引发 C6386 错误?
- 使用 memcpy 函数C++复制字符数组
- 如何使用strncpy_s复制字符数组
- 在结构之间复制字符数据
- std::逐字节复制字符向量
- 比strncpy更好地复制字符阵列的部分方法
- 使用"="运算符复制字符* 内容
- 用 0 复制字符数组中的短整数
- 使用指针重新复制字符数组并修剪前导空格
- C++ 使用 char* 复制字符数组(无字符串库)
- 复制 c++ 字符指针
- 使用rd_buf复制C++字符串会更改const对象
- 如何从字符串指针复制字符到字符串向量
- 字符串字面值操作-复制字符
- 在使用std::copy而不是std::memcpy复制字符时避免libc函数调用