2010-08-19 19 views
7

Estoy tratando de serializar un conjunto de estructuras en C++. Esto funciona muy bien para todos los datos, excepto un vector contenido en mi estructura. Puedo escribir los datos en el disco y luego leer todos los datos nuevamente en la memoria. El único problema es cuando intento acceder a un elemento del vector obtengo un error de segmentación. Mi código está abajo. Cualquier ayuda es muy apreciada.Serialización de estructuras complejas en C++

programa para escribir en el disco

int main { 
    struct Student one; 
    strcpy(one.FullName, "Ernestine Waller"); 
    strcpy(one.CompleteAddress, "824 Larson Drv, Silver Spring, MD 20910"); 
    one.Gender = 'F'; 
    one.LivesInASingleParentHome = true; 
    one.grades.push_back(80); 
    one.grades.push_back(90); 

    ofstream ofs("fifthgrade.ros", ios::binary); 
    ofs.write((char *)&one, sizeof(one)); 
    ofs.close(); 
} 

Programa para leer desde el disco

int main { 
    struct Student *two = (struct Student *) malloc(sizeof(struct Student));  
    ifstream ifs("fifthgrade.ros", ios::binary); 
    //cout << "Size of struct: " << size << endl; 
    ifs.read((char *)two, sizeof(struct Student)); 
    cout << "Student Name: " << two->FullName << endl; 
    cout << "First Grade: " << two->grades[0] << endl; 
    cout << "Second Grade: " << two->grades[1] << endl; 
    ifs.close(); 
    return 0; 
} 
+0

http://www.parashift.com/c++faq-lite/serialization.html – DumbCoder

+0

Boost serialización: http://www.boost.org/doc/libs/1_44_0/libs/serialization/doc/index. html – karlphillip

+0

Por favor incluya la declaración para 'Estudiante' –

Respuesta

7

Lo que está haciendo es tomar la copia de una región contigua de memoria en la que se ha almacenado one y escribió a disco. Esto funcionará bien para tipos de datos simples (POD en C++ jargan). El problema con los vectores es que un vector es un objeto complejo con punteros a otras regiones de la memoria. Estas otras regiones de memoria no existen cuando se deserializa one en two, por lo tanto, su falla de segmentación.

Desafortunadamente, no hay atajos, será necesario escribir algún formulario en el código de serialización personalizado para realizar el trabajo.

Como algunos ya han mencionado Boost Serialization pueden ayudar. Alternativamente, despliegue su propio.

5

Probablemente la versión más simple de la serialización de un vector que tiene una oportunidad de trabajar es algo así como:

your_stream << your_vector.size(); 
std::copy(your_vector.begin(), your_vector.end(), 
    std::ostream_iterator<your_vector::value_type>(your_stream, "\n")); 

lectura de nuevo es algo como:

size_t size; 
your_stream >> size; 
vector_two.resize(size); 
for (size_t i=0; i<size; i++) 
    your_stream >> vector_two[i]; 

Tenga en cuenta que esto no es particularmente eficiente - en particular, supone (básicamente) que los datos se almacenarán en formato de texto, que a menudo es bastante lento y ocupa más espacio (pero es fácil de leer, manipular, etc., por programas externos, lo que a menudo es útil) .