如何安全地将std :: vector的内容复制到c风格的静态数组?

时间:2009-03-11 06:34:26

标签: c++ arrays vector

我需要操纵涉及插入中间的固定数组中的数据。 而不是使用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.

请注意我使用vector而不是list或deque因为 像上面的代码一样的'中间插入'是一个特殊的问题。 它会发生在“最后插入”和 '随机访问元素'。
任何解决方案?

任何类似的答案:“你使用c ++,删除c风格的数组实现。 仅对所有数组实现使用向量“实际上并没有用。

感谢。

4 个答案:

答案 0 :(得分:18)

问题是你正在向向量中添加内容,因此最终会有比使用它初始化它的myarr数组更多的元素。

如果要将向量复制回数组,则需要将其调整大小:

myvec.resize( MAX_SIZE);

或者您可以限制复制的元素数量:

copy( myvec.begin(), myvec.begin()+MAX_SIZE, myarr);

如果您希望myarr数组包含所有元素,那么它需要大于MAX_SIZE,并且您已经找到了人们为什么建议使用vector而不是原始数组(vector知道如何增长,数组不知道。)

请注意,虽然您不希望'任何类似的答案:'您使用c ++,删除c样式数组实现。仅使用向量用于所有数组实现“',您通常可以使用{{1并将vector传递给期望原始数组的例程。出于这个原因,&myvec[0]需要像原始数组一样连续存储其元素。

由于您收到“不安全操作”警告,因此您使用的是Microsoft编译器。要安全地解决问题,您应该使用vector算法而不是checked_copy。作为Evgeny Lazin indicates,您可以为数组创建一个已检查的迭代器,以传递给copy算法。

使副本安全而不需要Microsoft扩展的其他选项是将数组包装在一个类(可能是模板化的)中,以跟踪数组大小并提供以安全的方式将数据复制到数组中的方法。 STLSoft's array_proxy templateBoost's boost::array之类的内容可能有所帮助。

答案 1 :(得分:3)

一般来说,我猜你可以这样做:

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情况)。

答案 2 :(得分:1)

您可以使用模板参数推导来查找绑定的数组:

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警告。它们旨在诱使您编写不可移植的代码。

答案 3 :(得分:0)

你可以这样做:

memcpy(myarr, &(myvec)[0], myvec.size())

编辑:就安全性而言,根据this,向量将数据存储在连续的内存段中,因此您可以“不仅使用迭代器而且还使用常规指向元素的指针上的偏移量来访问它们。” / p>