1

I try to test my GradeStat function, but it fails in main in the highlighted line: printf("%d", c[0]);.. It gives me ERROR: segmentation fault but I can't tell why..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int** GradeStat(int* Grades, int size_grades, int grd_range, int* count_grd, int* avg_grd) {
    const int len = 100/grd_range+1;
    int** collector = malloc(len * sizeof(int*));
    count_grd = calloc(len, sizeof(int));
    avg_grd = calloc(len, sizeof(int));
    size_t i;
    for(i=0; i<size_grades; i++)
        count_grd[Grades[i]/grd_range]++;
    for(i=0; i<len; i++) {
        if (count_grd[i] == 0)
            collector[i] = NULL;
        else
            collector[i] = malloc(count_grd[i] * sizeof(int));
    }
    int** temp = malloc(len * sizeof(int*));
    for(i=0; i<len; i++) {
        temp[i] = collector[i];
    }
    for(i=0; i<size_grades; i++) {
        *(collector[Grades[i]/grd_range]++) = Grades[i];
        avg_grd[Grades[i]/grd_range] += Grades[i]/count_grd[Grades[i]/grd_range];
    }
    for(i=0; i<len; i++) {
        collector[i] = temp[i];
    }
    free(temp);
    return collector;
}

int main() {
    int** arr;
    int grd[8] = {10, 43, 46, 49, 80, 60, 98, 100};
    int* c,a;
    arr = GradeStat(grd, 8, 10, c, a);
    ------>  printf("%d", c[0]);  <-------
    return 0;
}
Tal Rofe
  • 457
  • 12
  • 46
  • 2
    `count_grd` is a local variable. Setting it does not change the value of `c` in the caller. Need to pass in a pointer to the pointer if you want to change it inside the function. – kaylum Dec 31 '19 at 21:04
  • @kaylum So I should change it to `int** count_grd`? What if I'm forbidden to change it? – Tal Rofe Dec 31 '19 at 21:08
  • Yes. But I don't know what you mean by "forbidden to change it". An alternative is to have `main` define the array instead of allocating inside the function. But not sure if that meets your needs. – kaylum Dec 31 '19 at 21:11
  • @kaylum I need to implement the `GradeStat` function as given (cannot change the parameters). My `main` function is only for testing my implementation.. – Tal Rofe Dec 31 '19 at 21:15
  • Then I guess they are expecting you to pass in an array instead of allocating it in `GradeStat` as I stated. That's a requirements issue and you may need to clarify with your teaching staff if unsure. – kaylum Dec 31 '19 at 21:17
  • 2
    `a` is declared `int`, but it's being passed to an `int*` argument. You need to declare `a` as an array in `main()` just like `c`. – Barmar Dec 31 '19 at 21:38
  • @Barmar Thanks. I guess the correct format is to write `int *x` and not `int* x` – Tal Rofe Dec 31 '19 at 21:40
  • 2
    @TalRofe Yes, it's a common beginner error to think that `int* c,a;` means `int *c; int *a;`. The spacing is not significant in the language, but writing it that way will make it clearer to human readers. – Barmar Dec 31 '19 at 21:43
  • regarding: `int** temp = malloc(len * sizeof(int*));` This creates an array of pointers to pointers, however, where all those pointers are pointed to is never set to any specific value. Suggest each entry be set via a call to `malloc()`. – user3629249 Dec 31 '19 at 22:06
  • @Barmar, The kind of problem you have pointed out is why the axiom: *only one statement per line and (at most) one variable declaration per statement.* should be followed – user3629249 Dec 31 '19 at 22:39
  • Regarding the comment: *Thanks. I guess the correct format is to write int *x and not int* x* It makes absolutely no difference if the `*` is to the left, the right, or in the middle, – user3629249 Dec 31 '19 at 22:41
  • 1
    When one can't explain in a one-line comment what the allocation scheme is, it's time (for your teacher) to re-think the prototype of the function. – Neil Dec 31 '19 at 22:43

0 Answers0