1

I'm having trouble understanding struct pointers within struct. Could you try to explain it to me or recommend some interesting reading that explain the concept? I don't know if it is a too general question, in which case I'm sorry.

Example:

struct person{
    struct person* mother;
    struct person* father;
    int birthday;
};

struct person john;
struct person alice;
struct person rachael;
john.birthday = 1988;
alice.mother = &rachael;
alice.mother->birthday = 1970;
5
  • What don't you understand about it? Commented Apr 21, 2020 at 18:18
  • I don't understand very well what's mean the part about "alice.mother->birthday = 1970" and how the syntax is like that Commented Apr 21, 2020 at 18:20
  • When you have a pointer you need to de-reference it using either * before it or -> after it. A local structure uses . to access properties. Commented Apr 21, 2020 at 18:21
  • 1
    What don't you understand about that part? Commented Apr 21, 2020 at 18:21
  • There's nothing different about a pointer in a struct and a pointer in an ordinary variable. You use them exactly the same way. Commented Apr 21, 2020 at 18:27

2 Answers 2

1

so you have a struct that has pointer references to the same kind of struct, this is legal in C, whereas including a whole struct (and the memory for the elements) wouldn't work because it is recursive...

struct person{
int age; // sizeof(int) bytes
person mom; // sizeof(int) + sizeof person, which is sizeof int bytes + sizeof person...
};

that wouldn't work, because it would take infinite memory to store.

so you have to store a pointer to an instance, which is a variable that stores the address of an instance, or NULL (in a well behaved program it probably shouldn't be any other value)

struct person{
int age; // sizeof(int) bytes
person * mom; // sizeof (*person)...
};

so now we can start doing things

person QueenMother; // these have storage, but are garbage data
person QueenElizabethII;

both of those are on stack, all of the memory they use is used right there. as you pointed out you can make an assignment:

QueenElizabethII.mom = &QueenMother;

so the pointer to mom is the address of QueenMother... that works, now if you want to set the QueenMother's age through the QueenElizabethII instance you can.

(*QueenElizabethII.mom).age = 102; // dereference and dot accessor.
//which you could also write as
QueenElizabethII.mom->age = 102;  // pointer to member accessor 

now if we wanted to re-write this all dynamically we could do something like:

struct person{
int age; // sizeof(int) bytes
person * mom; // sizeof(int) + sizeof (*person)...
};

person * QueenMother; // these dont have storage yet; 
person * QueenElizabethII;

QueenElizabethII = malloc(sizeof(person)); // now we have storage, but the data is garbage... we can initialize it to 0 with memset, or bzero; or you can do this:
QueenMother = calloc(1,sizeof(person)); // calloc is like malloc, but it zero's the data in the return

QueenElizabethII->mother = QueenMother; // now this syntax is smoother
QueenElizabethII->age = 94;
QueenElizabethII->mother->age=102; // if you are so inclined.

one thing you always need to be aware of with this strategy is that you need to check that the pointers actually point somewhere or you will crash...

if(QueenElizabethII->mother){
    QueenElizabethII->mother->age=102; // now that is safe... probably
}

and I should add when you are done with the memory you should free it:

free(QueenElizabethII);
free(QueenMother);

Otherwise you have a leak

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much!!
1

From your comment, this part:

alice.mother->birthday = 1970;

Is equivalent to this:

(*(alice.mother)).birthday = 1970;

alice.mother is of type struct person*

(*(alice.mother)) dereferences the pointer, so the type is struct person

(*(alice.mother)).birthday gives you access to the birthday field of the struct person, so now you can assign a value to it.


C just provides syntactic sugar in the form of -> so that you don't have to write the alternative, which is an ugly mess

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.