I’ve got these two structs that I need to store in files. I can’t find a good way to get them into a file without parsing the struct and writing it as a text file, which is far less efficient than I’d like. What is the simplest way to get a struct of mostly primitives into a file? The structs are below
struct object
{
unsigned short id;
float x;
float y;
unsigned short type;
unsigned char flags;
};
struct sector
{
unsigned long id;
unsigned long neighbors[4]; // North,East,South,West
std::vector<object> objects;
};
I’ve tried the code below to write the struct to a file, but it doesn’t work very well. The size of the file after execution is only 4.7kb, while it should be much larger than that.
sector s;
object o;
s.id = 1;
s.neighbors = {2, 3, 4, 5};
o.id = 1; o.x = 2.0f; o.y = 3.0f; o.type = 4; o.flags = 6;
for(int i = 0; i < 65536; i++)
{
s.objects.push_back(o);
o.id += 1; o.x += 1.0f; o.y += 1.0f; o.type += 1; o.flags += 1;
}
ofstream os("world.dat", ios::binary|ios::out);
s.objects.resize(s.objects.size());
int size = s.objects.size() * sizeof(object);
os.write((char*)&size, sizeof(int));
os.write((char*)&s, size);
os.close();
Any suggestions?
You can’t write a struct containing a vector using raw byte I/O. The vector class is a small data structure that stores its data somewhere on the heap, not in the struct. This is because it is impossible for a struct to “know,” ahead of time, how many objects it will hold.
You can write the contents of the vector thus:
As to why the file ends up with only 4.7 kB in it, I don’t know. Print out
sizeto see how much data is being written. I checked the code after the above changes, and it works.Also, you don’t need
s.objects.resize(s.objects.size());. Resizing the vector to its own size is redundant.Also note a small quirk. sizeof(object) == 16 on my architecture, which is more than required for the above struct (2 + 4 + 4 + 2 + 1 == 13). The compiler usually adds padding to ensure that primitives of size 2n are aligned to a 2n-byte boundary, which results in holes inside each struct and between structs in the vector.
The consequence of this is that you are writing extra bytes to the file, some of which are random noise. In non-debug builds, those holes are never filled with anything, so they just contain whatever rubbish was at that memory location before it was allocated for your purposes. Therefore, if you run the program twice, it is possible that the two files will not be identical.