0
struct student{
    int id;
    int score;
};

struct student* allocate(){
     struct student* students = (struct student*)malloc(sizeof(struct student)*10);
     return students;
}


void generate(struct student* students){
     int i=0;
     printf("%lu\n", sizeof(students));
     printf("%lu\n", sizeof(struct student));
     int length = sizeof(students)/sizeof(struct student);
     printf("%d\n", length);
     for(i=0;i<length;i++){
          printf("hi\n");
     }
}

I have this code which should create an array of 10 student structs. When I get to the generate function and try to see how much memory the students array had allocated it only says 8 bytes, the same as a single student struct itself and when I get to the for loop it is only printing "hi" once when it should be 8 times. What have I done wrong?

Output:

8
8
1
hi
izzzi
  • 35
  • 5
  • 1
    "...to see how much memory the students array had allocated...". What made you believe that operator `sizeof` is suitable for that purpose? How did you come up with the idea of using `sizeof`? – AnT stands with Russia Sep 30 '16 at 00:47
  • 1
    sizeof(students) gives you the size of a pointer, not the size of the array. – Hans Passant Sep 30 '16 at 00:47
  • What would be the best way to get the size of the array then? – izzzi Sep 30 '16 at 00:49
  • @AnT Sorry dude I have only been using C for like 2 weeks. If you know a better way then let me know. – izzzi Sep 30 '16 at 00:50
  • @izzzi: I was not trying to be an arse or ask a rhetorical question. I really want to know whether you just *guessed* that the word "size" in `sizeof` makes it suitable for your purposes, or you came to that idea in some other way. I'm trying to understand the root of the confusion. – AnT stands with Russia Sep 30 '16 at 00:53
  • 1
    @izzzi: There's no standard way to retrieve the size of allocated memory block (e.g. an allocated array). If you need that size, you have to preserve it yourself, "manually". You knew that size at the moment of allocation. So keep it and carefully pass it around, so that you have access to it anywhere you need it. – AnT stands with Russia Sep 30 '16 at 00:55
  • It was my understanding that to calculate lengths of arrays in c you need to use `sizeof` to calculate the amount of bytes it take up and divide that by a single one of what you are storing in the array since there is no actual length option – izzzi Sep 30 '16 at 00:57
  • 2
    @izzzi: `sizeof` can only give you the compile-time size of some specific type. With arrays it only works with explicitly declared local or static objects of array type. Once you converted your array to an element pointer, it is no longer possible to obtain the original array size through `sizeof`. Applying `sizeof` to a pointer will simply give you pointer size (8 on your platform). – AnT stands with Russia Sep 30 '16 at 00:58
  • Alright I see what is wrong now. I thought I had seen somewhere before where something like what I did was possible but I guess not. Thanks for letting me know the correct way to deal with array lengths! – izzzi Sep 30 '16 at 01:03
  • Have linked to a question that explains your concerns – M.M Sep 30 '16 at 01:09

1 Answers1

3

What have I done wrong?

students is a pointer, so sizeof(students) gives you the size of a pointer. It does not give you the size of the array that students points to.

Frustratingly enough, sizeof(*students) also doesn't work - it gives you the size of one student, not the size of the whole array. That's because students only points to the first student, as far as the compiler is concerned.

There is no built-in way to get the size of an array, given a pointer to the start of it. You need to keep track of the size yourself.

user253751
  • 57,427
  • 7
  • 48
  • 90