问题
I am trying to write a function that returns the pointer of 2d array read from a binary file. Although I compile without error there is always a segmentation fault, when I try to print one of the elements of the array. Here my code:
double ** readArray(int rows, int cols)
{
int i;
double **myArray=malloc(rows*sizeof(double*));
if (myArray){
for (i=0; i < rows; i++)
{
myArray[i]=malloc(cols*sizeof(double));
}
}
FILE *data;
data=fopen("matrix.bin", "rb");
fread(myArray,sizeof(double),rows*cols,data);
return myArray;
}
int main ()
{
int cols = 7;
int rows = 15;
double **myArray=readArray(rows, cols);
printf("%f\n", myArray[1][0]);
return 0;
}
回答1:
The problem is that there is no 2D array in your code. The pointer-to-pointer look-up table thing is not a 2D array. It is [rows] number of segments scattered all over the heap, at random places. It is therefore also needlessly slow.
Also, you should keep memory allocation and algorithms separated.
Do something like this instead:
#include <stdio.h>
#include <stdlib.h>
void* allocArray (int rows, int cols)
{
return malloc( sizeof(double[rows][cols]) ); // allocate 1 2D-array
}
void readArray (int rows, int cols, double array[rows][cols])
{
FILE *data;
data=fopen("matrix.bin", "rb");
fread(array, sizeof(double[rows][cols]), 1, data); // read 1 2D-array
}
int main ()
{
int cols = 7;
int rows = 15;
double (*myArray)[cols] = allocArray(rows, cols);
readArray(rows, cols, myArray);
printf("%f\n", myArray[1][0]);
free(myArray); // free 1 2D-array
return 0;
}
The reason for the peculiar declaration double (*myArray)[cols] instead of the more logical double (*myArray)[rows][cols], is that we want to avoid the inconvenient array pointer de-referencing syntax. (*myArray)[1][0] is not easy to read. So instead of declaring an array pointer to a 2D array, declare an array pointer to a 1D array, then use pointer indexing on that array pointer. For any pointer, any_pointer[n] gives pointed-at item number n. Array pointers are no difference, so you get 1D array number n.
回答2:
Your fread() call is overwriting all those pointers you painfully set up.
You need to read a single row at a time, and use the set-up pointer to store to:
for(size_t i = 0; i < rows; ++i)
fread(myArray[i], cols * sizeof *myArray[i], data);
Also, when doing I/O and memory allocation you should check the return values too, of course.
来源:https://stackoverflow.com/questions/35599371/reading-2d-array-from-binary-file-and-return-the-pointer-this-array-in-c