I did this plenty of times but suddenly I can't get over this error. I've got a simple input.txt file with this structure:
3 4
2 1 1
1 2 3
8 3 3
Where the first line is basically the matrix's size and then follows value row col each line. I'm using calloc so the matrix is set to 0 and then reading the file I replace the values and their position. And exactly in the readFile() function i get "segmentation fault", I guess when it tries to replace the values in the matrix. As a consequence what I'm trying to get is this:
2 0 0 0
0 0 1 0
0 0 8 0
void readSize(FILE *fp, int *rows, int *cols) {
fscanf(fp, "%d %d", rows, cols);
}
void readFile (FILE *fp, int **A) {
int val, row, col;
val = row = col = 0;
char buffer[100];
fgets(buffer, 100, fp); //* skip first line
while(!feof(fp)) {
fscanf(fp, "%d %d %d", &val, &row, &col);
A[row][col] = val;
val = row = col = 0;
}
}
int **allocMatrix(int m, int n) {
int **A = (int** )calloc(m, sizeof(int* ));
for( int i = 0; i < m; i++) *(A + i) = (int* )calloc(n, sizeof(int));
if (A == NULL) {
handleErr(ALLOC_ERR);
free(A);
}
return A;
}
int main() {
FILE *fp = fopen(INPUT, "r");
if (fp == NULL) handleErr(READ_FILE_ERR);
int **A, m, n; //! m -> rows | n -> cols
readSize(fp, &m, &n);
A = allocMatrix(m, n);
readFile(fp, A);
fclose(fp);
printMatrix(A, m, n);
return 0;
}
The code has several minor mistakes. The bug you are specifically looking for appears to be A[row][col] = val;
. Since you've allocated a pointer table of size 3x4, you cannot access array item [3][3]
in that array, since arrays are 0-indexed in C. Your input file appears to be 1-indexed.
One way to rewrite the code into using proper 2D arrays instead would be something like this:
readSize(fp, &m, &n);
int (*A)[n+1] = allocMatrix(m,n);
...
free(A);
With the function properly rewritten as:
void* allocMatrix(int m, int n)
{
int (*A)[n+1] = calloc( 1, sizeof(int[m+1][n+1]) );
if(A == NULL)
{
handleErr(ALLOC_ERR);;
}
return A;
}
You can rewrite the other functions to work with 2D arrays too, for example:
void readFile (FILE *fp, int x, int y, int A[x][y])
Then ideally check if the read row
and cols
are inside the bounds of x
and y
before accessing that location.
You should also check the result of fscanf
instead of incorrectly using while(!feof(fp))
. In case fscanf
fail you currently still try to access the data read, which is wrong.