2012-01-15 8 views
8

que estaba buscando sobre este tema y he encontrado muchas maneras de convertir una matriz [] a un std :: vector, como el uso de:Copia de una matriz en un std :: vector

assign(a, a + n) 

o, directamente en las el constructor:

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

los solucionar mi problema, pero me pregunto si es posible (y correcta) que debe hacer:

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

me pregunto esto porque tengo el siguiente código:

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; 
} 

Y me gustaría hacer:

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; 
} 

(He quitado el tratamiento de error de la función ReadFile para simplificar el post).

Está funcionando, pero tengo miedo de que no sea seguro. Creo que está bien, ya que la memoria utilizada por el vector es continua, pero nunca he visto a alguien usando vectores de esta manera.

¿Es correcto usar vectores como este? ¿Hay alguna otra mejor opción?

Respuesta

8

Sí, es seguro con std::vector C++ standard garantiza que los elementos se almacenarán en ubicaciones de memoria contigua.

C++ 11 estándar:

23.3.6.1 visión general templatevector Clase [vector.overview]

Un vector es un contenedor de secuencias que soporta iteradores de acceso aleatorio. Además, respalda (amortiza) las operaciones de inserción y borrado de tiempo constante al final; insertar y borrar en el medio toma tiempo lineal. La administración del almacenamiento se maneja automáticamente, aunque se pueden dar sugerencias para mejorar la eficiencia. Los elementos de un vector se almacenan contiguamente, lo que significa que ifv es avector dondeT es un tipo distinto de bool, entonces obedece a la identidad & v [n] == & v [0] + n para todos 0 < = n < v .tamaño().

1

Haga su ajuste de tamaño primero, y debería funcionar bien.

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

He * does * resize primero (vea la primera línea de su función). – celtschk

+1

No estaba insinuando que no lo hizo. Estaba enfatizando su importancia. – TheBuzzSaw

+1

Es posible que no haya * querido decir * que lo insinúe, pero lo hizo. – celtschk

2

La memoria en vector se garantiza que se asignen de manera contigua, y unsigned char es POD, por lo tanto, es totalmente seguro para memcpy en él (asumiendo que no copia más de que ha asignado, por supuesto).

1

Sí, la solución que usa memcpy es correcta; el buffer mantenido por vector es contiguo. Pero no es del todo seguro, por lo que prefiere assign o std::copy.

5

Sí, está bien hacer eso. Es posible que desee hacer myvet.data() en lugar de &myvet[0] si le parece mejor, pero ambos tienen el mismo efecto.Además, si las circunstancias lo permiten, puede usar std::copy en su lugar y tener más seguridad de tipo y todos esos otros objetos de biblioteca estándar de C++.

Se garantiza que el almacenamiento que usa vector es contiguo, lo que lo hace adecuado para usarlo como un búfer o con otras funciones.

Asegúrese de que no se modifique la vector (como llamar a push_back en él, etc) mientras se está utilizando el puntero que se obtiene de data o &v[0] porque el vector podría cambiar el tamaño de su memoria intermedia en una de esas operaciones e invalidar el puntero.

3

Este enfoque es correcto, solo depende del vector que tenga la memoria contigua que requiere la norma. Creo que en C++ 11 hay una nueva función de miembro data() en vectores que devuelve un puntero al búfer. También tenga en cuenta que en el caso de `memcpy necesita pasar el tamaño en bytes no el tamaño de la matriz

Cuestiones relacionadas