简体   繁体   中英

Copying an array into a std::vector

I was searching about this topic and I found many ways to convert an array[] to an std::vector, like using:

assign(a, a + n)

or, direct in the constructor:

std::vector<unsigned char> v ( a, a + n );

Those solve my problem, but I am wondering if it is possible (and correct) to do:

myvet.resize( 10 );
memcpy( &myvet[0], buffer, 10 );

I am wondering this because I have the following code:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read( std::vector< uint8_t >& bufferRead, int32_t totalToRead )
{
    uint8_t* data = new uint8_t[totalToRead];
    DWORD totalRead;
    ReadFile( mhFile, data, totalToRead, &totalRead, NULL );
    bufferRead.resize( totalRead );
    bufferRead.assign( data, data + totalRead );
    delete[] data;

    return IDiskAccess::READ_OK;
}

And I would like to do:

IDiskAccess::ERetRead nsDisks::DiskAccess::Read( std::vector< uint8_t >& bufferRead, int32_t totalToRead )
{
    bufferRead.resize( totalToRead );
    DWORD totalRead;
    ReadFile( mhFile, &bufferRead[0], totalToRead, &totalRead, NULL );
    bufferRead.resize( totalRead );

    return IDiskAccess::READ_OK;
}

(I have removed the error treatment of the ReadFile function to simplify the post).

It is working, but I am affraid that it is not safe. I believe it is ok, as the memory used by the vector is continuous, but I've never seen someone using vectors this way.

Is it correct to use vectors like this? Is there any other better option?

Yes it is safe with std::vector C++ standard guarantees that the elements will be stored at contiguous memory locations.

C++11 Standard:

23.3.6.1 Class templatevector overview [vector.overview]

A vector is a sequence container that supports random access iterators. In addition,itsupports(amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously , meaning that ifv is avector whereT is some type other than bool, then it obeys the identity&v[n] == &v[0] + n for all0 <= n < v.size().

Yes, it is fine to do that. You might want to do myvet.data() instead of &myvet[0] if it looks better to you, but they both have the same effect. Also, if circumstances permit, you can use std::copy instead and have more type-safety and all those other C++ standard library goodies.

The storage that a vector uses is guaranteed to be contiguous, which makes it suitable for use as a buffer or with other functions.

Make sure that you don't modify the vector (such as calling push_back on it, etc) while you are using the pointer you get from data or &v[0] because the vector could resize its buffer on one of those operations and invalidate the pointer.

That approach is correct, it only depends on the vector having contiguous memory which is required by the standard. I believe that in c++11 there is a new data() member function in vectors that returns a pointer to the buffer. Also note that in the case of `memcpy you need to pass the size in bytes not e size of the array

在存储vector是保证连续分配和unsigned char是POD,因此这是完全安全的memcpy到它(假设你没有拷贝,当然比你更已分配)。

Do your resize first , and it should work fine.

vector<int> v;
v.resize(100);
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int));

Yes, the solution using memcpy is correct; the buffer held by a vector is contiguous. But it's not quite type-safe, so prefer assign or std::copy .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM