Home > other >  "segmentation fault" when assigning values to a specific position in a dynamically allocat
"segmentation fault" when assigning values to a specific position in a dynamically allocat

Time:01-25

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

CodePudding user response:

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.

  • Related