object serialization, segmentation fault

Hi All,

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:

write_obj.cpp
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
#include <fstream>
#include <iostream>
using namespace 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;
}



read_obj.cpp
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
#include <fstream>
#include <iostream>
using namespace std;

class Person
{
public:
	string	name ;
	int	age;
	
	Person()
	{
		}

	Person(string nn, int aa)
	{
		name = nn ;
		age = aa ;
		}
};

int main()
{
	Person two;

	ifstream input_file("data.dat", ios::binary);
	input_file.read((char *)&two, sizeof(two));

	cout << "Object Information\n";
	cout << "Name: " << two.name << endl;
	cout << "Age:  " << two.age << endl;
	
	input_file.close() ;

	return 0;
}



I'd really appreciate any help anyone might be able to provide.

Many thanks in advance!
Last edited on
output_file.write((char *)&one, sizeof(one))

You can't do this since your class/struct contains an std::string. You'll have to write your own save/load methods.
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.
Last edited on
Thanks guys!

After reading your replies and further searching ( http://www.cplusplus.com/forum/beginner/30826/ ), I think I now get it.

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.

Many thanks for your feedback and help.

All the best!
Topic archived. No new replies allowed.