如何安全地将 std::vector 的内容复制到 c 风格的静态数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/633549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to copy the contents of std::vector to c-style static array,safely?
提问by mhd
I need to manipulate data in fixed array involving mid insertion. Rather than using memcpy,etc. I want to use vector. I have problem when I want to copy the vector elements back to the c-style array. Here's the code:
我需要在涉及中间插入的固定数组中操作数据。而不是使用 memcpy 等。我想使用矢量。当我想将向量元素复制回 c 样式数组时遇到问题。这是代码:
void tryvector()
{
using namespace std;
const int MAX_SIZE=16;
BYTE myarr[MAX_SIZE]={0xb0,0x45,0x47,0xba,0x11,0x12, 0x4e};
vector<BYTE> myvec (myarr, myarr+MAX_SIZE);
vector<BYTE>::iterator it;
printf("myarr pre :");
for(int i=0;i<MAX_SIZE;++i){
printf("%02x ", myarr[i]) ;
}
printf("\nmyvec pre :")
for(it=myvec.begin(); it<myvec.end();++it){
cout<<hex<<static_cast<int>(*it)<<" ";
}
it = myvec.begin()+ 3;
myvec.insert(it,0x5f);
printf("\nmyvec post:");
for(it=myvec.begin(); it<myvec.end();++it){
cout<<hex<<static_cast<int>(*it)<<" ";
}
copy(myvec.begin(), myvec.end(), myarr); //???
printf("\nmyarr post:");
for(int i=0;i<MAX_SIZE;++i){
printf("%02x ", myarr[i]) ;
}
}
I'm using vs 2005.
Here's the warning:
我正在使用 vs 2005。这是警告:
warning C4996: 'std::_Copy_opt' was declared deprecated
1> c:\program files\microsoft visual studio 8\vc\include\xutility(2270) : see declaration of 'std::_Copy_opt'
1> Message: 'You have used a std:: construct that is not safe. See documentation on how to use the Safe Standard C++ Library'
1> c:\documents and settings\mhd\my documents\tesvector.cpp(50) : see reference to function template instantiation '_OutIt std::copy<std::_Vector_iterator<_Ty,_Alloc>,BYTE*>(_InIt,_InIt,_OutIt)' being compiled
1> with
1> [
1> _OutIt=BYTE *,
1> _Ty=BYTE,
1> _Alloc=std::allocator<BYTE>,
1> _InIt=std::_Vector_iterator<BYTE,std::allocator<BYTE>>
1> ]
When I run it , I got the following run-time error:
当我运行它时,出现以下运行时错误:
Run-Time Check Failure #2 - Stack around the variable 'myarr' was corrupted.
Please note that I use vector instead list or deque because
the 'middle insertion' like the code above is juat a particular problem.
It will happen less than 'inserting at the end' and
'random access of element'.
Any solution ?
请注意,我使用 vector 而不是 list 或 deque,因为像上面的代码这样的“中间插入”是一个特定的问题。它会比“在最后插入”和“元素的随机访问”发生得少。
任何解决方案?
Any answer that resembles:"You use c++, drop the c style array implementation. Use only vector for all array implementation" is not really helpful.
任何类似于:“您使用 c++,删除 c 样式数组实现。仅对所有数组实现使用向量”的任何答案都没有真正的帮助。
Thanks.
谢谢。
回答by Michael Burr
The problem is that you're adding things to the vector so it ends up with more elements than were in the myarr
array that you initialized it with.
问题是您正在向向量添加内容,因此它最终包含的元素比myarr
您初始化它的数组中的元素多。
If you want to copy the vector back into the array, you'll need to size it down:
如果要将向量复制回数组,则需要缩小其大小:
myvec.resize( MAX_SIZE);
Or you could limit the number of elements you copy back:
或者您可以限制您复制回来的元素数量:
copy( myvec.begin(), myvec.begin()+MAX_SIZE, myarr);
If you want the myarr
array to contain all the elements, then it needs to be larger than MAX_SIZE
, and you've found out why people suggest to use vector
rather than raw arrays (vector
s know how to grow, arrays do not).
如果您希望myarr
数组包含所有元素,则它需要大于MAX_SIZE
,并且您已经发现人们建议使用vector
而不是原始数组的原因(vector
知道如何增长,数组不知道)。
Note that while you don't want 'Any answer that resembles:"You use c++, drop the c style array implementation. Use only vector for all array implementation"', you can often get away with using a vector
and passing &myvec[0]
to routines that expect a raw array. vector
is required to store its elements contiguously just like a raw array for just this reason.
请注意,虽然您不想要“任何类似于:”您使用 c++ 的答案,请删除 c 样式数组实现。仅对所有数组实现使用向量“”,但您通常可以使用 avector
并传递&myvec[0]
给期望的例程原始数组。 vector
出于这个原因,需要像原始数组一样连续存储其元素。
Since you're getting the 'unsafe operation' warning, you're using Microsoft's compiler. To fix the problem safely, you're supposed to use the checked_copy
algorithm instead of copy
. As Evgeny Lazin indicates, you can create a checked iterator for your array to pass to the checked_copy
algorithm.
由于您收到“不安全操作”警告,因此您使用的是 Microsoft 的编译器。为了安全地解决问题,您应该使用checked_copy
算法而不是copy
. 正如Evgeny Lazin 指出的那样,您可以为数组创建一个检查迭代器以传递给checked_copy
算法。
Other options to make the copy safe that do not require Microsoft extensions would be to wrap the array in a class (possibly templated) that keeps track of the array size and provides methods to copy data into the array in a safe manner. Something like STLSoft's array_proxy
templateor Boost's boost::array
might help.
其他不需要 Microsoft 扩展的使复制安全的选项是将数组包装在一个类中(可能是模板化的),该类跟踪数组大小并提供以安全方式将数据复制到数组中的方法。STLSoft 的array_proxy
模板或Boost 之boost::array
类的东西可能会有所帮助。
回答by unwind
In general, I guess you could do something like this:
一般来说,我想你可以这样做:
void *myarr;
if((myarr = malloc(myvec.size() * sizeof myvec[0])) != NULL)
{
memcpy(myarr, &myvec[0], myvec.size() * sizeof myvec[0]);
/* Do stuff with the C-style array for a while
.
.
.
*/
free(myarr); /* Don't forget handing back the memory when done. */
}
This allocates a new C-style array to hold the vector's elements, and copies the data in place. This way the there is no need to match the sizes statically.
这会分配一个新的 C 样式数组来保存向量的元素,并将数据复制到位。这样就不需要静态匹配大小。
Of course, this is general so it just gives you a void *
to access your C array with, so you need to either cast or just change the type to the actual type (BYTE
in this case).
当然,这是通用的,所以它只是让你void *
访问你的 C 数组,所以你需要强制转换或只是将类型更改为实际类型(BYTE
在这种情况下)。
回答by MSalters
You can use template argument deduction to find the array bound:
您可以使用模板参数推导来查找数组绑定:
template<typename T, size_t N>
size_t copy(std::vector<T> const& src, T[N] dest) {
size_t count = std::min(N, src.size());
std::copy(src.begin(), src.begin()+count, dest);
return count;
}
Turn off the Microsoft warnings about unchecked stuff. They're aimed at luring you into writing unportable code.
关闭有关未检查内容的 Microsoft 警告。它们旨在引诱您编写不可移植的代码。
回答by i_am_jorf
You can do:
你可以做:
memcpy(myarr, &(myvec)[0], myvec.size())
Edit: As far as safety goes, according to this, vectors store data in contiguous segments of memory, so you can access them "not only using iterators but also using offsets on regular pointers to elements."
编辑:就安全而言,根据this,向量将数据存储在连续的内存段中,因此您可以“不仅使用迭代器,还可以使用指向元素的常规指针上的偏移量”访问它们。