0

I am required to store a matrix o N students with 4 fields (number, grade1, grade2 and average). This could be achieved with a struct, but that is not the purpose of this exercise. Once the data is collected (read_data), it must be sorted according to the average (sort_matrix). However, when more than 4 or more students are inserted, a segmentation fault happens. I have been unable to detect the origin n of the problem. What am I missing? Relevant code is bellow.

void read_data(float **mtx, int *size){
    float num, grade1, grade2;

    while( scanf("%f %f %f", &num, &grade1, &grade2)==3 ){
        (*size)++;
        mtx = (float**)realloc(mtx, (*size)*sizeof(float*) );
        mtx[*size-1] = (float*)malloc(4*sizeof(float));
        mtx[*size-1][0] = num;
        mtx[*size-1][1] = grade1;
        mtx[*size-1][2] = grade2;
        mtx[*size-1][3] = (grade1+grade2)/2;
    }
    printf("Done reading\n");
}


void sort_matrix(float **mtx, int size){
    int i=0, j=0;
    float *aux = NULL;

    for(i=0; i<size-1; i++){
        for(j = 0; j<size-1-i; j++){
            if(mtx[j][3] > mtx[j+1][3]){
                aux = mtx[j];
                mtx[j] = mtx[j+1];
                mtx[j+1]=aux;
            }
        }
    }
    printf("Done sorting\n");
}

int main(void){
    float **mtx =(float**)malloc(0);
    int size=0;

    read_data(mtx, &size);
    sort_matrix(mtx, size);
    print_matrix(mtx, size);
    return 0;

}

EDIT: Following the answers given bellow, I have found this topic which proved to be useful. The problem turned out to be changing the size of mtx without passing the pointer address. For the sorting function, there is no need to pass the address because even though the addresses the mtx array points to will change, the size will not.

Community
  • 1
  • 1
AmiguelS
  • 805
  • 2
  • 10
  • 28

3 Answers3

6

You almost had it.

You passed the address of size to read_data so size could be changed within that function, but did not pass the address of mtx, so it does not reflect the allocations done within read_data.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
1

If you want to allocate a matrix within a function you need to pass a pointer to that matrix. i.e. you want to allocate a float** matrix therefore you need to pass a float *** to your function.

Edit: Or you could just return the matrix.

apokryfos
  • 38,771
  • 9
  • 70
  • 114
1

As Scott has pointed out that you are not passing the address of mtx to read_data(). You want a solution something like this:

void read_data(float ***mtx, int *size){
    float num, grade1, grade2;


    while( scanf("%f %f %f", &num, &grade1, &grade2)==3 ){
        (*size)++;
        (*mtx) = (float**)realloc(*mtx, (*size)*sizeof(float*) );
        (*mtx)[*size-1] = (float*)malloc(4*sizeof(float));
        (*mtx)[*size-1][0] = num;
        (*mtx)[*size-1][1] = grade1;
        (*mtx)[*size-1][2] = grade2;
        (*mtx)[*size-1][3] = (grade1+grade2)/2;
    }
    printf("Done reading\n");
}


void sort_matrix(float ***mtxt, int *sz){
    int i=0, j=0;
    float *aux = NULL;
    int size=*sz;
    float **mtx=*mtxt;

    for(i=0; i<size-1; i++){
        for(j = 0; j<size-1-i; j++){
            if(mtx[j][3] > mtx[j+1][3]){
                aux = mtx[j];
                mtx[j] = mtx[j+1];
                mtx[j+1]=aux;
            }
        }
    }
    printf("Done sorting\n");
}

int main(void){
    float **mtx =(float**)malloc(0);
    int size=0;

    read_data(&mtx, &size);
    printf("Size = %d",size);
    sort_matrix(&mtx, &size);
    print_matrix(&mtx, size);
    return 0;

}
jada12276
  • 129
  • 8