簡體   English   中英

如何安全地將 std::vector 的內容復制到 c 風格的 static 數組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM