Can't write objects to binary file .

HI!
My program runs correctly , but I think instead of writing objects itself , it writes their address , Because when I run functions "SaveToBinary" and "LoadFromBinary" after each other the information are loaded correctly . (Becasue the program is running on same memory) But if I run function "SaveToBuinary" and then close the program and open it again and run LoadFromBinary , then a runtime error occurs .
I think my problem is with that "&" sign before objects in "read" and "write" functions .
I still don't know why should I use them .
I want to save the objects (and its properties) and NOT their reference to address .

These are my functions :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef GENERALFUNCS_H_INCLUDED
#define GENERALFUNCS_H_INCLUDED

int SaveToBinary () //Reads all the students from student.txt (which consist of text-format record fields) and writes them in binary form to a new file
{
    string Path ;
    cout << "\n\nEnter the full path and name of the file you wnat to save the current state of institution to :\n" ;
    cin >> Path ;
    fstream BinaryOutput (Path.c_str () , ios::out | ios::binary) ; //This is the file which the binary information are going to be saved
    vector <Student> Students ; //This vector will keep the content of student.txt as Student objects
    Students = GetStudentsBinary() ; //This function returns a "vector <Student>" and I assign it to my Students vector
    unsigned int MySize = Students.size () ; //Number of students
    BinaryOutput.write ((char *) & MySize , sizeof (unsigned int)) ; //At the beginning of file I write the number of Students which are going to be written in binary file
    vector <Student> :: iterator it ;
    for (it = Students.begin () ; it != Students.end () ; it ++)
    {
        Student tmp ;
        tmp = * it ; //Every time I assign the object which "it" points to , to a student
        MySize = sizeof (tmp) ; //And get it's size
        BinaryOutput.write ((char *) &MySize , sizeof (unsigned int)) ; //And for every stdent, I write it's size
        BinaryOutput.write ((char *) &tmp , MySize) ; //And then itself
        /*
        **I'm not sure if those assignments are necessary , but I was just trying to see where si the problem
        */
    }
    return 1 ; //Binary file written successfully
}

int LoadFromBinary () //Loads the students using the format which is saved by SaveToBinary
{
    string Path ;
    cout << "\n\nEnter the full path and name of the file you wnat to load state of institution from :\n" ;
    cin >> Path ;
    fstream BinaryInput (Path.c_str () , ios::in | ios::binary) ;
    vector <Student> Students ; //I store Student objects in this vector
    unsigned int Quantity ; //N umber of students saved in file
    BinaryInput.read ((char *) &Quantity , sizeof (unsigned int)) ;
    for (unsigned int i = 0 ; i < Quantity ; i++)
    {
        Student tmp ; //I read students temporarily in this
        unsigned int MySize ;
        BinaryInput.read ((char *) &MySize , sizeof (unsigned int)) ; //Size of next student object in file
        BinaryInput.read ((char *) &tmp , MySize) ;
        cout << "TEST" ;
        cout << tmp.GetFirstName() ; //Testing if the students are written in file correctly BUT THEY DIDN"T
        cout << "TEST" ;
        Students.push_back (tmp) ; //I store them in Students vector later
    }
    return 1 ;
}

#endif // GENERALFUNCS_H_INCLUDED 


This is my student class :
1
2
3
4
5
6
7
8
9
10
11
class Student
{
//Functions omitted
private :
    char * FirstName ;
    char * LastName ;
    char * ID ;
    char * LastCertificate ;
    char * Major ;
    Date DateRegistered ;
};


For "char *"s , in their "set" function, I allocate space for them .
And Date class is a class with 3 "int"s .
Thank you !

If any additional explanations and codes are necessary let me know .
Last edited on
1
2
3
        Student tmp ;
        tmp = * it;
        MySize = sizeof (tmp) ; //this is a constant, computed at compile time 


> I think instead of writing objects itself , it writes their address
You are writing the objects, ¿but do you realize what is the object content?
Thanks @ne555
YES ! I checked their content (Their FirstName and DateRegisterd)
It was correct ;
You absolutely must NOT write non-POD types to a file in this manner.

I explain the reasons why and what is considered a "POD type" in this thread here:
http://www.cplusplus.com/forum/general/111793/

This:
1
2
3
        Student tmp ;
        tmp = * it ; //Every time I assign the object which "it" points to , to a student
        MySize = sizeof (tmp) ; //And get it's size 


is almost always the wrong way to write a binary file.

And in fact, in your case, it is absolutely wrong because Student is not a POD type (it contains pointers).

(EDIT: in your case... when you write the Student to a file... you are not writing their name/ID/etc to the file... you are just writing pointer to the file. The data you're interested in is not the pointer... but what the pointer points to. So when you load the file... you load the pointers, but the data they point to probably doesn't exist any more.)


So yeah.... read my replies in that thread I linked. And read this article:
http://www.cplusplus.com/articles/DzywvCM9/
Last edited on
Topic archived. No new replies allowed.