0

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!

3
  • 1
    sizeof(data) doesn't mean what you think it means. It's a size of the pointer. Also you'll get better help if you post the stacktrace when your app crashes (you may also even figure out why it does). Running the app via valgrind will also give you some answers. Commented Feb 26, 2016 at 3:23
  • C allows variable-sized arrays, so you can declare double data[N][M];. Then you can read the entire file into the array in one step. Commented Feb 26, 2016 at 3:54
  • @Barmar C does not allow variable sized arrays, Major compilers still often only support C89/C90. It was added as an enhancement in C99, and GCC supports it in C90 and C++, but it was actually taken out of the C11 standard as required, so you cannot rely on it being portable. Commented Feb 26, 2016 at 4:04

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

That got it. Thanks for the quick response!
@user4272082 Glad to help. As a note, marking the question as answered is proper form at this point.
It should be &data[ii][jj].
@user4272082 In addition to what Michael said about the sizeof, Barmar correctly points out that you are not allocating your data into one large datablock, so even in you had the full size, your read still would have failed.
1

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.