Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying an array into a std::vector

Tags:

c++

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?

like image 823
Renan Greinert Avatar asked Jan 15 '12 17:01

Renan Greinert


People also ask

Can I assign an array to a vector in C++?

C++ In C++, the Vector class provides a constructor which accepts a range, so to create a vector from array elements, pass the pointer to the first and last position of the range as the argument during the vector initialization that needs to be copied to the vector i.e, (arr, arr+N).

Can we assign array to vector?

Assigning array elements while declaring a vectorWhen we declare a vector we can assign array elements by specifying the range [start, end] of an array.

How do I cast an array to a vector?

To convert an array to vector, you can use the constructor of Vector, or use a looping statement to add each element of array to vector using push_back() function.

How do you store an array in vector?

You cannot store arrays in a vector or any other container. The type of the elements to be stored in a container (called the container's value type) must be both copy constructible and assignable. Arrays are neither.


2 Answers

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().

like image 55
Alok Save Avatar answered Nov 07 '22 13:11

Alok Save


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.

like image 5
Seth Carnegie Avatar answered Nov 07 '22 14:11

Seth Carnegie