idigyourpast
idigyourpast

Reputation: 714

Pointers and loops in C

Please know that I'm still very new to C and pointers in general... This is for a class so I'm not asking for explicit code, only help understanding the concepts.

I'm trying to create a loop to assign random values to an int within a struct. The problem occurs when I'm assigning values to the current iteration of my pointer or array.

struct student{
    int id;
    int score;
};

struct student* allocate(){
    /*Allocate memory for ten students*/
    int ROSTER_SIZE = 10;
    struct student *roster = malloc(ROSTER_SIZE * sizeof(struct student));

    /*return the pointer*/
    return roster;
}

void generate(struct student* students){
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
    int i = 0;

    for (i = 0; i < 10; ++i) {
        students[i]->id = i + 1;
        students[i]->score = rand()%101;
}

Now, from my understanding, which is most likely incorrect, I should be able to use students[i] to assign values to each iteration, but VS 2010 tells me "the expression must have a pointer type." Isn't it already a pointer? It's passed into the function as a pointer, right?

Upvotes: 9

Views: 1841

Answers (4)

Paul R
Paul R

Reputation: 213200

Change:

students[i]->id = i + 1;
students[i]->score = rand()%101;

to:

students[i].id = i + 1;
students[i].score = rand()%101;

Reason: students is a pointer to an array of struct student. students[i] is an an actual struct student. Note that students[i] is actually equivalent to *(students + i).

Upvotes: 7

Jimmy Lu
Jimmy Lu

Reputation: 5100

Paul's answer will fix your problem. But since you are asking to understand the concept...

Basically, what you did was to dynamically allocate an array of data on the heap. Now that students is indeed a pointer to the array of Student on the heap. However, when you refer to it as students[index], you are actually doing something like this

*(students + index)

You are referring to a Student instance at the location of (students + index). Note that it is already de-referenced, so you are referring to that instance directly already. Hence, when you write students[index]->id, it is the same as

*(students + index)->id

It should be clear to you now that this is simply not the correct syntax. You should instead write

students[index].id

which is equivalent to

(*(students + index)).id

This really means: you are incrementing the pointer called students by index * sizeof(Student) bytes in memory, and access its id field.

Upvotes: 1

user529758
user529758

Reputation:

Isn't it (students[i]) already a pointer?

No. After you dereference it (remember: using the array subscription syntax ptr[index] on pointers means *(ptr + index)!), it will be a plain struct, for which you should use the . field member accessor syntax instead of the -> which is for pointers to structures:

students[i].id = i + 1;

etc. should be fine.

Upvotes: 3

hexist
hexist

Reputation: 5250

students is a pointer, but when you index it then you are refering to an actual instance of the structure, so hence you'll need to use . instead of -> to access a field in that structure

Upvotes: 5

Related Questions