-3

The problem: I'm having a problem with reading and writing files in binary mode using C++ stl only. What I have in my class are 2 integer member to tell me the matrix's size and the actual matrix itself. The matrix is dynamic though which I think is the main reason why non of my read request is correct. So my question is how do I read/write for class with dynamic arrays member.

What I've tried: reading in the size of the matrix before hands and then allocate memory for the matrix array. But for some reason my debugger just keeps saying it's segmentation fault although I have made some room for it. I've even tried to make two class with the same member values, still nothing

class MaTrix{
private :
    int row, column;
    float ** maTrix_arr;
}
void outFile(){
    ofstream of("matrix.inp", ios::binary | ios::app) ;
    of.write(reinterperted_cast<char*>(this), sizeof(*this)) ;
}
void inFile(){
    ifstream ifs("matrix.inp", ios::binary | ios::app) ; // if I don't use app it will delete my file for some reason
    // I do some more allocation here to make sure the Matrix is of suitable size
    // Long code short I tried to get the two integers row and column out and it works as intended
    // Then I allocate some memory for this->maTrix_arr, also making sure I reset the file pointer
    ifs.read(reinterperted_cast<char*>(this), sizeof(*this)) ;
}
};
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 2
    You're attempting to write and read *pointers* (it seems). A pointer is local to the currently running process, it will not be valid in any other process, not even a process running the same program. – Some programmer dude Dec 31 '18 at 18:28
  • 1
    As for *one* possible way to solve the problem, just write and read *text*. Write each "row" of the matrix as a separate line in the file. That way it's actually very easy to read and write the data. And if you use `std::vector` instead, then it becomes even easier. – Some programmer dude Dec 31 '18 at 18:30
  • 1
    Write the *data* that is represented by the matrix, not the pointers. – PaulMcKenzie Dec 31 '18 at 18:30
  • Can you elaborate on this – Trai Việt Nam Dec 31 '18 at 18:31
  • I wanted to read everything in one go, that's why I've used binary mode, other than that I thought this pointer here meant that the data is being writen/read, not the pointer itself – Trai Việt Nam Dec 31 '18 at 18:33
  • You will find plenty of "elaboration" in your C++ book, specifically the chapters that explains what pointers are, and how to use them. In the meantime, try to wrap your brain around something very simple: `sizeof()` is a compile-time constant. The `sizeof` of your object is always the same, where your matrix has just one or two values, or several trillion. It's the size of two integers, and a pointer. On modern 64 bit platforms, your `sizeof()` will always evaluate to 24. If you doubt that, just `std::cout << sizeof(*this)`. Think about it. – Sam Varshavchik Dec 31 '18 at 18:34
  • I still need to allocate more memory for the actual array before reading it right ? – Trai Việt Nam Dec 31 '18 at 18:39
  • The thing is even when I have or have not allocate memory for the array, it would still get segmentation fault – Trai Việt Nam Dec 31 '18 at 18:47
  • Oh boy nvm I just realized it now, I'm so dumb – Trai Việt Nam Dec 31 '18 at 18:53
  • How is your file formatted? – ats Dec 31 '18 at 19:00
  • @TraiViệtNam To add to SamV's comment, if you need to be further convinced, open the file you saved in a text editor. Does what you see make any sense? It won't make sense. So how are you going to turn that gibberish you see into real data? Sorry, but no amount of magic will turn that file back into the original data. – PaulMcKenzie Dec 31 '18 at 19:22

1 Answers1

2

What you really want is some serialization library. And you probably want to use containers, so you would serialize some std::vector<double> for a vector, and you would define your own template matrix<typename ElementType> (or better yet find one, perhaps in Boost, which fits your needs). You certainly need to define the abstract data type for your matrixes (so the collection of all the operations on them). BTW, this answer (for C) and that one could inspire you.

You obviously should not write raw pointers in a file, because they make sense only for your process. Even if you run the same program in the same state (e.g. same matrixes) in two different processes, they would use different pointer addresses (e.g. because of ASLR). You want to write (and later read) the contents of your matrixes.

You might be interested in existing serialization libraries such as s11n, or at least in neutral binary formats such as XDR or ASN1. You probably should care about endianess (e.g. if reading on a Sparc or ARM computer a binary file written on x86).

You could decide to serialize in some textual format (or text-based protocol), such as JSON (or YAML, etc...). This is more friendly to developers (and for debugging). You can find a lot of JSON related libraries for C++, e.g. jsoncpp.

If you are not allowed to use external libraries, you could reinvent and document (perhaps in EBNF notation) your textual serialization format (inspired by JSON, or by S-exprs) and easily implement it (using usual parsing techniques, such as recursive descent parser).

If you are required to use a binary format, you need to specify it (again EBNF notation should help) and implement it (again, it is a parsing problem for the decoding; encoding is usually much simpler).

Very probably, you want to encode (and decode) each matrix element one by one. That is not a big deal, once your abstract data type has the operations to fetch (and perhaps to change) the value of some individual matrix element.

Read also How to debug small programs

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547