简体   繁体   English

我可以使用std :: copy将数据的位模式从整数向量复制到无符号char数组中

[英]Can I use std::copy to copy bit pattern of data from vector of integers to an array of unsigned char

Recently I have been trying to update some code to utilise the standard C++ library functions rather than old C style functions. 最近,我一直在尝试更新一些代码以利用标准的C ++库函数,而不是旧的C样式函数。 In particular, I tried to do the following (artificial working example for simplicity - i know the code is ugly but it illustrates the problem concisely) : 特别是,我尝试执行以下操作(为简化起见,使用人工工作示例-我知道代码很丑陋,但它简洁地说明了问题):

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);

I was expecting that this would behave in a similar way to the code that I am trying to replace : 我期望它的行为与我尝试替换的代码类似:

memcpy(szBuffer,&vData[0],sizeof(int)*vData.size());

but debugging the code, it is clear that the std::copy code I have written is only writing to the first 4 bytes of the unsigned char buffer instead of the full bit pattern of the 4 integers in the vector. 但调试代码后,很明显,我编写的std::copy代码仅写入unsigned char缓冲区的前4个字节,而不是向量中4个整数的完整位模式。 Can someone tell me what I have done wrong, or is it simply that I cannot use std::copy in this way and should stick with memcpy ? 有人可以告诉我我做错了什么吗,还是仅仅因为我不能以这种方式使用std::copy而应该坚持使用memcpy

Stick to memcpy , std::copy is being intelligent, it understands the types involved and is correctly converting int to unsigned char using standard conversions. 坚持使用memcpystd::copy是智能的,它了解所涉及的类型,并使用标准转换将int正确转换为unsigned char memcpy is ignorant, that's what you want. memcpy是无知的,这就是您想要的。

I was expecting that this would behave in a similar way to the code that I am trying to replace ... 我期望它的行为与我尝试替换的代码类似...

That std::copy as written cannot behave in a similar way to a std::memcpy or std::memmove because the type mismatch between the elements of std::vector<int> versus elements of unsigned char szBuffer[100] . 编写的std::copy不能以类似于std::memcpystd::memmove因为std::vector<int>元素与unsigned char szBuffer[100]的元素之间的类型不匹配。 One way to overcome this type mismatch is to cast that szBuffer to an int* : 克服此类型不匹配的一种方法是将szBuffer转换为int*

std::copy(vData.begin(),vData.end(),reinterpret_cast<int*>(szBuffer));

That reinterpret_cast is a personal preference issue. reinterpret_cast是个人喜好问题。 I'd much rather see something that screams "Danger, danger, Will Robinson!" 我宁愿看到尖叫的东西“危险,危险,威尔·罗宾逊!” for something that can invoke undefined behavior over a C-style cast that hides but does not remove the potential for UB. 可以通过隐藏但不会消除UB潜力的C样式转换调用未定义行为的东西。 I (and my project manager overlords) can grep for reinterpret_cast . 我(和我的项目经理霸主)可以grep来获取reinterpret_cast

The potential for UB here is real as there is no guarantee that this cast is valid due to alignment issues. 此处UB的潜力是真实的,因为不能保证由于对齐问题而导致此强制转换有效。

Note also that there is no guarantee that std::copy will ever be implemented via memcpy or memmove . 还要注意,不能保证std::copy可以通过memcpymemmove来实现。 There is not one word in the standard (either 2003 or 2011) that says that std::copy needs to be implemented via memcpy or memmove if possible. 标准(2003年或2011年)中没有一个词表明std::copy需要通过memcpymemmove实现。 (Aside: In every implementation I've seen, std::copy will be implemented via std::memmove if doing so would work "as if" the naive implementation had been employed.) (旁白:在每一个我所见过的实施, std::copy将通过实施std::memmove ,如果这样做“好像”天真的实现已经使用是可行的。)

The only reason to switch from std::memcpy to std::copy here is aesthetics. std::memcpy切换到std::copy的唯一原因是美观。 Sometimes aesthetics get in the way. 有时美学会妨碍您。 "Foolish consistency is the hobgoblin of small minds." “愚蠢的一致性是小头脑的妖精。” I recommend sticking with std::memcpy . 我建议坚持使用std::memcpy It does exactly what you want, and this usage is safe because there's no overlap and because the buffer is properly sized. 它完全可以满足您的要求,并且这种用法是安全的,因为没有重叠,并且缓冲区大小适当。

because the standard of is that the behaviour (if not the exact implementation) of std::copy is equivalent to: 因为标准是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;
  }
}

which means it copies member-by-member, incrementing each iterator and returns the next write position in the output. 这意味着它逐个成员地复制,递增每个迭代器并返回输出中的下一个写入位置。

This is not the same behaviour as memcpy which is what you actually want here. 这与memcpy的行为不同,这是您实际上想要的。 There is nothing wrong with using memcpy (even if a certain Microsoft compiler tells you it is unsafe, which it can be but so is driving a truck if you don't drive it properly, that doesn't mean nobody can ever drive one). 使用memcpy并没有错(即使某个Microsoft编译器告诉您它是不安全的,也可能是不安全的,但是如果您没有正确驾驶它,那么驾驶卡车也是如此,这并不意味着没有人可以驾驶一辆) 。

To interpret the vector's contents as raw memory, use reinterpret_cast to unsigned char * : 要将向量的内容解释为原始内存,请使用reinterpret_castunsigned char *

std::copy(reinterpret_cast<unsigned char *>(&*vData.begin()),
          reinterpret_cast<unsigned char *>(&*vData.end()), szBuffer);

You need to indirect and take the address of the begin and end elements because it is not guaranteed that vector::iterator is a pointer type. 您需要间接获取begin和end元素的地址,因为不能保证vector::iterator是指针类型。

This is one of the few guaranteed safe uses of reinterpret_cast . 这是保证对reinterpret_cast安全使用的少数几个方法之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用std :: copy将char数组中的两个字节复制到unsigned short中 - Use std::copy to copy two bytes from a char array into an unsigned short 如何将 std::string 复制到无符号字符数组? - How to copy a std::string to unsigned char array? 如何将`std :: string`转换为`std :: vector <unsigned char> `没有复制? - How do I cast `std::string` to `std::vector<unsigned char>` without making a copy? 给定一个填充无符号字符**的 C 函数,如何在没有中间副本的情况下使用数据填充 std::vector - Given a C function that populates a unsigned char**, how to populate a std::vector with the data without an intermediate copy 如何使用memcpy将数据从两个整数复制到一个字符数组? - How can I use memcpy to copy data from two integers to an array of characters? 当类具有`unsigned char &amp;operator[]`时如何使用std::copy - How to use std::copy when class has `unsigned char &operator[]` 我该如何投射一个std :: vector <const unsigned char> 到const std :: vector <unsigned char> ? - How can I cast an std::vector<const unsigned char> to a const std::vector<unsigned char>? 我怎样才能转换const std :: vector <unsigned char> 去char - How can I convert const std::vector<unsigned char> to char 如何将char数组中的一系列数据复制到向量中? - How to copy a range of data from char array into a vector? 如何将数据从`boost :: scoped_array`复制到`std :: vector` - How to copy data from `boost::scoped_array` to `std::vector`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM