File I/O With Double Pointer?

I've been toying around with File I/O in C++ for about a day now, and cannot quite figure out how to write a double pointer (It's for a Multidimensional Array) to a file. Everytime I try to write it, it just writes garbage, which leads me to believe that 1) I'm doing something wrong, and 2) I am writing data to a file I don't have access too (oops).

My guess is, I am not converting my Array to a (char *) correctly. I'm not quite sure how you would do that in the first place as I've never worked with double pointers before.

This small program emulates my problem:

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
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <fstream>

#define ARRAY_WIDTH 5
#define ARRAY_HEIGHT 5

using namespace std;

class cFoo
{
	private:
		int val1;
		int val2;
	public:
		cFoo();
};

cFoo::cFoo()
{
	val1 = 1;
	val2 = 2;
}

void WriteFile(cFoo **inBar);

int main()
{
	long i = 0;
	long k = 0;
	cFoo **Bar = new cFoo*[ARRAY_WIDTH];
	

	// Setup Array
	for(i = 0; i < ARRAY_WIDTH; i++)
	{
		Bar[i] = new cFoo[ARRAY_HEIGHT];
	}

	// Write File
	WriteFile(Bar);

	// Clean up Memory
	for(i = 0; i < ARRAY_WIDTH; i++)
	{
		delete [] Bar[i];
	}

	delete [] Bar;

	cin >> k;

	return 0;
}

void WriteFile(cFoo **inBar)
{
	ofstream fsFile;

	fsFile.open("somefile.txt", ios::out | ios:: binary | ios::trunc);
	
	fsFile.write((char *)inBar,sizeof(cFoo) * (ARRAY_WIDTH * ARRAY_HEIGHT));

	fsFile.close();
}


So yeah, I'm stumped on what to do. :(
Surely you want to save the actual data; not the value of a pointer, which will simply be a memory address.
You say that it "just writes garbage". But what are you expecting the contents of your array to look like in a file?

Furthermore you are writing your array as if it was one contiguous lump of memory. But this is not how you allocated it:
1
2
3
4
5
6
7
	cFoo **Bar = new cFoo*[ARRAY_WIDTH];

	// Setup Array
	for(i = 0; i < ARRAY_WIDTH; i++)
	{
		Bar[i] = new cFoo[ARRAY_HEIGHT];
	}

You have one lump of memory to contain pointers, each one pointing to a separate lump of memory. Your array is likely to be dotted all around your memory. It is not likely to all be in a neat contiguous lump!

Personally I would consider writing out the textual representation of the values a bit like this:
1
2
3
for(size_t x = 0; x < ARRAY_WIDTH; ++x)
    for(size_t y = 0; y < ARRAY_HEIGHT; ++y)
        fsFile << inBar[x][y] << '\n';

Last edited on
The file should look like a series of NULs and STX/SOH in notepad++ (As I know what the data looks like written to a file), which is what I use to see if what I wrote to it worked correctly.

And, oh. I hadn't realized that's what I was doing. Oops :P I knew the thing about memory, I just thinking too hard, thank you for pointing that out to me! :) If anyone is interested in how I solved this, this is the changed code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void WriteFile(cFoo **inBar)
{
	long i = 0;

	ofstream fsFile;

	fsFile.open("somefile.txt", ios::out | ios::binary | ios::trunc);
	
	for(i = 0; i < ARRAY_WIDTH; i++)
	{
		fsFile.write((char *)inBar[i],sizeof(cFoo) * ARRAY_HEIGHT);
	}

	fsFile.close();
}


BTW A textual representation would be valid, but a dramatic waste of space when the integers get to values like 31722. I would much prefer a Binary approach, sure if the space was maybe one or two digits that would be good, but at that point I'd probably opt for using bytes/chars for file size reasons.
Topic archived. No new replies allowed.