[英]How to copy the contents of std::vector to c-style static array,safely?
我需要在涉及中間插入的固定數組中操作數據。 而不是使用 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]) ;
}
}
我正在使用 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> ]
當我運行它時,出現以下運行時錯誤:
Run-Time Check Failure #2 - Stack around the variable 'myarr' was corrupted.
請注意,我使用向量而不是列表或雙端隊列,因為像上面的代碼這樣的“中間插入”是一個特殊的問題。 它發生的次數少於“在末尾插入”和“元素的隨機訪問”。
有什么解決辦法嗎?
任何類似的答案:“您使用 c++,放棄 c 樣式的數組實現。對所有數組實現僅使用向量”並不是很有幫助。
謝謝。
問題是您正在向向量添加東西,因此它最終的元素比您初始化它的myarr
數組中的元素多。
如果要將向量復制回數組中,則需要將其縮小:
myvec.resize( MAX_SIZE);
或者您可以限制復制回的元素數量:
copy( myvec.begin(), myvec.begin()+MAX_SIZE, myarr);
如果您希望myarr
數組包含所有元素,那么它需要大於MAX_SIZE
,並且您已經發現為什么人們建議使用vector
而不是原始 arrays ( vector
知道如何增長, arrays 不知道)。
請注意,雖然您不想要“任何類似的答案:“您使用 c++,刪除 c 樣式的數組實現。僅對所有數組實現使用向量”,您通常可以使用vector
並傳遞&myvec[0]
到需要原始數組的例程。 由於這個原因, vector
需要像原始數組一樣連續存儲其元素。
由於您收到“不安全操作”警告,因此您使用的是 Microsoft 的編譯器。 為了安全地解決問題,您應該使用checked_copy
算法而不是copy
。 正如Evgeny Lazin 所指出的,您可以為您的數組創建一個檢查迭代器以傳遞給checked_copy
算法。
使復制安全且不需要 Microsoft 擴展的其他選項是將數組包裝在 class(可能是模板化的)中,它跟蹤數組大小並提供以安全方式將數據復制到數組中的方法。 STLSoft 的array_proxy
模板或Boost 的boost::array
可能會有所幫助。
一般來說,我想你可以這樣做:
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. */
}
這將分配一個新的 C 樣式數組來保存向量的元素,並將數據復制到位。 這樣就不需要靜態匹配大小。
當然,這是通用的,所以它只是給你一個void *
來訪問你的 C 數組,所以你需要轉換或只是將類型更改為實際類型(在這種情況下為BYTE
)。
您可以使用模板參數推導來查找數組綁定:
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;
}
關閉有關未檢查內容的 Microsoft 警告。 它們旨在引誘您編寫不可移植的代碼。
你可以做:
memcpy(myarr, &(myvec)[0], myvec.size())
編輯:就安全而言,據此,向量將數據存儲在 memory 的連續段中,因此您可以“不僅使用迭代器,還可以使用指向元素的常規指針的偏移量”訪問它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.