Reputation: 3436
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?
Upvotes: 8
Views: 13364
Reputation: 208323
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
Upvotes: 3
Reputation: 75130
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.
Upvotes: 5
Reputation: 363517
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
.
Upvotes: 2
Reputation: 206508
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().
Upvotes: 9
Reputation: 19721
The memory in vector
is guaranteed to be allocated contiguously, and unsigned char is POD, therefore it is totally safe to memcpy
into it (assuming you don't copy more than you have allocated, of course).
Upvotes: 2
Reputation: 8826
Do your resize first, and it should work fine.
vector<int> v;
v.resize(100);
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int));
Upvotes: 1