I've just completed a C++ course with Koenig in India, but am having problems with serialization.
Specifically, I get a segmentation fault (core dumped), when reading an object from a saved file.
Unfortunately, the instructor couldn't tell me what was going on and simply kept saying it was a problem with gcc (which I very much doubt) and the fact that I'm using Linux, as he had his version working on his MS Visual Studio laptop.
The code is quite simple. I have two files, the first of which writes the object to a file, and the second opens the previously created file to read the object. I understand that a class's attributes shouldn't necessarily be public, but I've tried to keep it as simple as possible (to remove any ambiguity/errors), since the main issue I have is with regard to reading the object, and not specifically any style of coding. Here's the code from my two files:
#include <fstream>
#include <iostream>
usingnamespace std;
class Person
{
public:
string name ;
int age;
Person(string nn, int aa)
{
name = nn ;
age = aa ;
}
};
int main()
{
Person one("Natalia", 17);
ofstream output_file("data.dat", ios::binary);
output_file.write((char *)&one, sizeof(one));
return 0;
}
The problem is due to the fact that the class member name is itself an instance of the string class, which holds dynamic data. Basically, you are writing the value of a memory address to a file and then reading it back. This value is obviously invalid, hence the segment fault.
Try changing the size of the string passed to the constructor in write_obj.cpp, and you should notice that the size of the file data.dat does not change.
With the Microsoft compiler, I had to include <string> to compile read_obj.cpp.
Oddly enough, write_obj.cpp compiled as is.
On Windows the program appeared to work. sizeof(Person) evaluates to 32.
However, any string data containing more than 16 characters (including the terminating null) results in either incorrect output, or a memory access violation. This might indicate that there is indeed an implementation difference when it comes to the string class, however that fact that the read program worked at all might have been a fluke and shouldn't be relied on.
You would probably want to write serialization routines that write and read each member individually.
The object being read contains a string (which itself is not the actual text data, but a pointer to it) and therefore when the file is re-opened and read it's pointing to a different/invalid address, which gives the segmentation fault.
I had also noticed that the size of the file wasn't changing, and thanks to you guys I now now why.