2011-09-09 12 views
6

Quiero leer N bytes de datos de un flujo de archivos y anexarlos a un vector. Así que vamos a decir que tenemos unLeer N bytes del archivo y anexarlos a un estándar :: vector

basic_ifstream<uint8_t> myFileStream; 

y una

vector<uint8_t> myBuffer; 

Actualmente estoy haciendo algo como esto:

myBuffer.reserve(N); 
for (int i=0; i<N; ++i) 
{ 
    uint8_t tmpByte; 
    myFileStream.read(&tmpByte, 1); 
    myBuffer.push_back(tmpByte); 
} 

pero esto es extremadamente lento.

Ahora traté de dejar que myFileStream.read copie los datos directamente en el vector. Desde un vector almacena sus elementos en un lugar de almacenamiento contiguo, pensé que algo como esto debería ser posible:

uint8_t* ptr = &myBuffer.back(); // there is already some elements in the buffer (I know) 
ptr++; // first element after existing data 
myBuffer.resize(myBuffer.size() + N); 
myFileStream.read(ptr, N); 

Pero con esto me sale un error de tiempo de ejecución (la corrupción del montón). ¿Qué está mal con esta solución? ¿O hay una mejor manera de hacer esto de todos modos?

Respuesta

12

Su problema es que resize puede necesitar reasignar el vector completo, y así invalidar su anterior ptr. Debe tomar el puntero solo después de resize.

std::size_t oldSize = myBuffer.size(); 
// resize first 
myBuffer.resize(oldSize + N); 
uint8_t* ptr = &myBuffer[oldSize]; // already first element after existing data 
myFileStream.read(ptr, N); 

Tenga en cuenta que como prima esta aplicación funcionará incluso si el vector original está vacía (por N != 0, por supuesto).

+0

ahora funciona :) ¡gracias por su ayuda! –

+4

@Ajeet: 'reserve()' no cambia el 'tamaño()' del contenedor. Valoro la corrección sobre el rendimiento. –

+0

Es cierto. Sería útil solo si estuviera usando push_back(). Borrando mi comentario Gracias @R. Martinho –

Cuestiones relacionadas