Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving C++ result in binary file for later use

I am writing a C++ program that solves a PDE and saves the solution in a 2D array. Then it does something with the results of this PDE. However, solving the PDE accurately takes a lot of computations. Thus, the solving part has to be executed only once, but the results should be saved, such that I can get back to them later.

Therefore, I wrote two different codes:

  1. solves the pde and saves results in matrix A. Matrix A is saved in a binary file.

  2. Reads the values in the binary file and does computations with the results.

However, when I read the binary file in the second code, it only an empty array and does not contain the values that I saved here in the other code.

If I read it in code 1, it does function as desired.

What am I doing wrong? Is it even possible to read the values of a binary file in an other application? Should I approach this problem completely different?

I saved both codes in a different project, should I somehow link them? Or should both codes be in the same project?

I spend a few days searching the web for a solution, but I only find questions and answers on how to open and save binary files within the same code (for instance this and this). Does that mean that what I am trying to do is not possible or did I not find the correct sources?

I am a complete beginner in C++ and would be very happy with any help or directions.

Many thanks in advance!

This is code 1:

#include <iostream>
using namespace std;
#include <math.h>
#include <getopt.h>
#include <fstream>
#include <string>

// Returns a pointer-to-pointer to a newly created array
// of size [row : col].
double **Create2D(int row, int col)
{
    double **p = new double* [row];
    for (int j = 0; j < row; j ++)
        p[j] = new double[col];
    return p;
}

// Deletes an array pointed by 'p' that has 'row' number rows
void Delete2D(double **p, int row)
{
    for (int j = 0; j < row; j ++)
        delete [] p[j];
    delete [] p;
}

double PDE (double A_old, double A_old2, double dt, double s_int, double m, double ds, double R, double d){
    double A_next;
    A_next = A_old + dt*(s_int - 1)*m*A_old + (dt/ds)*((s_int-1)*(R*s_int-d)*(A_old2-A_old));
    return A_next;
}

// Start of main function

int main(int argc, char *argv[]) {

    // Set default values for input

    double t(1), m(0.5) , R (1.3) , d (0.8) ;

    // Solution by solving PDE for PGF

    double dt = 0.0003;
    const int tsteps = t/dt +1;
    const double ads = 0.01;
    const double ds = 0.01;
    const int ssteps = 1/ds +1;


    // Start Active Section
    double **A = Create2D(ssteps, tsteps);

    // Initial condition 1: f(s,0) = 1

    int i = 0;
    for (;i<ssteps;){
        A[i][0] = 1;
        i++;
    }

    // Initial condition 2: f(1,t) = 1

    int j = 0;
    for (;j<tsteps;){
        A[ssteps-1][j] = 1;
        j++;
    }

    // Calculate other matrix points
    int ii = ssteps-2;
    double as_int;
    as_int = 1-ads;

    for (;ii>=0;){
        int jj = 0;
        for (;jj<tsteps-1;){
            A[ii][jj+1] = PDE (A[ii][jj], A[ii+1][jj], dt, as_int, m, ds, R, d);
            jj++;
        }
        as_int = as_int-ds;
        ii--;
    }


    // Write A to a binary document

    ofstream out("valuesA", ios::out | ios::binary);
    if(!out) {
        cout << "Cannot open file.";
        return 1;
    }

    out.write((char *) &A, sizeof A);

    out.close();

    ifstream in("valuesA", ios::in | ios::binary);
    in.read((char *) &A, sizeof A);

    // see how many bytes have been read
    cout << in.gcount() << " bytes read\n";

    in.close();

    // Delete A from the heap to prevent memory leaking
    Delete2D(A, ssteps);

    return 0;
} // end main

This is code 2:

#include <iostream>
using namespace std;
#include <math.h>
#include <getopt.h>
#include <fstream>
#include <string>

double **Create2D(int row, int col)
{
    double **p = new double* [row];
    for (int j = 0; j < row; j ++)
        p[j] = new double[col];
    return p;
}

// Start of main function

int main(int argc, char *argv[]) {

    // Use output of PDE function
    double dt = 0.0003;
    const int tsteps = t/dt +1;
    const double ds = 0.01;
    const int ssteps = 1/ds +1;

    double **A = Create2D(ssteps, tsteps);

    ifstream in("valuesA", ios::in | ios::binary);
    in.read((char *) &A, sizeof A);

    // see how many bytes have been read
    cout << in.gcount() << " bytes read\n";

    in.close();

    return 0;
} // end main
like image 272
Judith Bouman Avatar asked Jan 29 '23 07:01

Judith Bouman


2 Answers

One major problem is this:

out.write((char *) &A, sizeof A);

Here you write the location of A, not the data it points to. Furthermore, since A is a pointer, then sizeof A will be the size of the pointer and not what it points to.

You need to loop and save each sub-array of A explicitly:

for (int i = 0; i < ssteps; ++i)
    out.write((char *) A[i], tsteps * sizeof(double));

Do the opposite when reading.

like image 165
Some programmer dude Avatar answered Feb 03 '23 23:02

Some programmer dude


I think your problem is solved by @SomeProgrammerDude, but I suggest to have a look at boost serialization.

Thus, you can easily write and read the state of complete objects and you don't have to invent your own binary representation of your data.

like image 39
schorsch312 Avatar answered Feb 04 '23 00:02

schorsch312