user4272082
user4272082

Reputation: 3

fread'ing a binary file into a dynamically allocated C array

Just a quick comment to start: While there are similar threads to this one, I haven't quite been able to find the solution I'm looking for. My problem is the following: I have 2D arrays of doulbes saved to binary files and I would like to read the binary files (using C code) into a 2D array. Additionally, I need to allocate the memory dynamically as the shape of the arrays will be changing in my application. To get started, I tried the following code:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main(){

int N = 10; //number of rows of 2D array
int M = 20; //number of columns

/* first allocate the array */

double **data;

data = (double **)malloc(N*sizeof(double *));

for(unsigned int i=0; i < N; i++) {

    data[i] = (double *)malloc(sizeof(double)*M);

    }


FILE *ptr;
ptr = fopen("random_real_matrix.dat", "rb");

fread(data, sizeof(data), 1, ptr);

for(unsigned int i=0; i<10;i++){


    for(unsigned int j=0; j<20;j++){
            fprintf(stderr, "m[%d][%d] = %f\n ", i, j, data[i][j]);

            }
     }

}

Unfortunately, this code segfaults. I checked to see if I can set the array entries like

d[0][0] = 235;

and that works fine. Assuming this approach can be fixed, I'm also interested to know if it could be extended to read to an array of double complex's.

Any advice would be greatly appreciated!

Upvotes: 0

Views: 2259

Answers (2)

Barmar
Barmar

Reputation: 781004

Because you allocated each row separately, you can't read into the entire array at once. You need to do it row by row.

for (int i = 0; i < N; i++) {
    fread(data[i], sizeof(double), M, ptr);
}

Upvotes: 1

Michael Albers
Michael Albers

Reputation: 3779

Your fread statement is incorrect. It's a common beginner mistake to think that sizeof gets the size of a dynamically allocated array. It doesn't. In this case it just returns the size of a double **. You will need to read in each double in the file and put that into the correct spot in the array.

for (int ii = 0; ii < N; ++ii)
{
   for (int jj = 0; jj < M; ++jj)
   {
     fread(data[ii][jj], sizeof(double), 1, ptr);
     // Be sure to check status of fread
   }
}

You can do this with a single for loop (or a single fread) but this is probably clearer to read.

Upvotes: 1

Related Questions