Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy the contents of std::vector to c-style static array,safely?

Tags:

c++

arrays

vector

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:

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:

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 ?

Any answer that resembles:"You use c++, drop the c style array implementation. Use only vector for all array implementation" is not really helpful.

Thanks.

like image 848
mhd Avatar asked Mar 11 '09 06:03

mhd


1 Answers

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.

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 (vectors know how to grow, arrays do not).

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.

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.

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 template or Boost's boost::array might help.

like image 161
Michael Burr Avatar answered Oct 23 '22 17:10

Michael Burr