Reputation: 809
I have a struct. I would like to have an array in this struct, and then write this to a binary file, and then read it. However this array should be dynamically allocated. I'm not sure how should I approach this. My current guess is this:
I define and then write the struct to the file like this:
struct map {
int *tiles;
};
int main() {
map sample;
sample.tiles = new int[2];
sample.tiles[0]=1;
sample.tiles[1]=2;
ofstream file("sample.data", ios::binary);
file.write((char *)&sample, sizeof(sample));
file.close();
return 0;
}
Then read it like this in another program:
map test;
ifstream file("sample.data", ios::binary);
file.read((char *)&test, sizeof(test));
When I want to check the results with
cout << test.tiles[0];
I get a weirdly huge number, but clearly not the number I originally wrote to the file.
What is the right way to do this? How can I read an array without knowing its size?
Upvotes: 0
Views: 576
Reputation: 118445
file.write((char *)&sample, sizeof(sample));
This writes to the file the following structure:
struct map {
int *tiles;
};
That is, a structure that contains a single pointer. A pointer is an address in memory. So, what you end up writing to the file is one, meaningless, raw, memory address.
Which, obviously, is of absolutely no use, whatsoever, when it gets read back later. You did not write any of your integers to your file, just what their address in memory was, in a program that long ago terminated.
In order to do this correctly, you will need to:
Record how many int
-egers the tiles
pointer is pointing to.
fwrite()
not the structure itself, but the integers that the tiles
pointer is pointing to.
You will also need to write, to the file, how many integers there are in this array. If the file contains only these integers, this is not really needed, since you can simply read the entire contents of the file. But, if you expect to write some additional data in the file, it obviously becomes necessary to also record the size of the written array, in the file itself, so that it's possible to figure it out how many integers there are, when reading them back. The simplest way to do this is to write a single int
, the size of the array first, followed by the contents of the array itself. And do the reverse process, when reading everything back.
Upvotes: 3
Reputation: 2185
Your sample
object contains a pointer tiles
and it's the pointer value that you're writing to the file. What you want to write is what the pointer points at.
In your example, you'd want to do file.write(sample.tiles, 2*sizeof(*sample.tiles));
. It's 2*
because you did new int[2]
. In general, you'd also want to save the size (2 in this case) in the file so you know how many ints to read back in. In this simple case you could infer the 2 from the size of the file.
Upvotes: 1