3

I compiled the code below on gcc(x64).

Why can I access the structure items by putting dot(people[0].name) rather than '->'?

Isn't people[0] is pointing to the address of the structure and I should use people[0]->name or (*people[0]).name to access the name?

Code:

#include <stdio.h>

#define TOTAL 4

int main(void) {
    typedef struct tagPerson {
        char name[12];
        int ID;
    } Person;

    #define LPPERSON Person*

    Person * people = calloc(sizeof(Person), TOTAL);
    strncpy(people[0].name, "Henry", 12);
    strncpy(people[1].name, "Jacob", 12);

    printf("sizeof(people)=%d\n", sizeof(people));
    printf("people[0].name=%s\n", people[0].name);
    printf("sizeof(people[0])=%d\n", sizeof(people[0]));
    printf("people[1].name=%s\n", people[1].name);
    printf("sizeof(people[1])=%d\n", sizeof(people[1]));

    free(people);

    return 0;
}

Output:

sizeof(people)=8

people[0].name=Henry
sizeof(people[0])=16

people[1].name=Jacob
sizeof(people[1])=16
3
  • 2
    You have switched the arguments in the call to calloc. Commented Aug 6, 2016 at 17:01
  • Isn't calloc only return a pointer to the lowest byte in the allocated memory? Commented Aug 6, 2016 at 17:05
  • Your use of strncpy() is dangerous. (well, every use of strncpy() is dangerous ...) Commented Aug 6, 2016 at 17:21

3 Answers 3

2

people is a pointer to Person. E1[E2] is an array subscript operation, that is equal to *((E1) + (E2)) (6.5.2.1). Here E1 must be pointer to T and E2 must be of an integer type. Type of whole expression is simply T. In your case E1 is a pointer to Person, so people[0] has type of Person, and access to fields is performed via . instead of ->.

If you want to use arrow - you can do it in next way:

(people + 1)->name; /* the same as people[1].name */
Sign up to request clarification or add additional context in comments.

Comments

1

Person * people means that:

data type of people is Person *, i.e. pointer to Person.

and;

datatype of *people is Person, i.e. a Person data type. And similary, datatype of *(people + index) is also a Person.

And because, people[index] is internally converted into *(people + index), the datatype of people[index] is Person- and NOT apointer to Person.

Since people[index] is of datatype Person, and not a pointer to Person, you access its members using the . operator, and NOT the -> operator.

Comments

0

Because people is an array of person structs, not pointers. If your array contained pointers, you would need to use the arrow notation. You can create structs without using pointers, and arrays of structs.

2 Comments

The variable people is not an array, but it points to memory that can be used as one.
That's true. It's also true of arrays in general, so I don't know how helpful the distinction is.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.