0

I'm quite new to C and I know that * is a pointer.

 Person * father = (Person *) malloc(sizeof(Person));
 Marriage * marriage = (Marriage *) malloc(sizeof(Marriage));
 (* marriage).male = father;

My question here is why does the * sometimes come before and sometimes after? What is the reason for this?

unalignedmemoryaccess
  • 7,246
  • 2
  • 25
  • 40
KB_Shayan
  • 632
  • 8
  • 24
  • Search for *pointer dereference*, *pointer variable declaration* and *pointer casting*. – unalignedmemoryaccess May 27 '18 at 22:19
  • 4
    Btw, [stop casting `malloc` in C programs](https://stackoverflow.com/a/605858/1322972) – WhozCraig May 27 '18 at 22:20
  • It might be easier to understand if you remove the unnecessary casts `(Person *)` and `(Marriage *)` of the value returned by `malloc`. Also `(* marriage).male = father;` might be better implemented as the more idiomatic `marriage->male = father;` – Weather Vane May 27 '18 at 22:29
  • @WhozCraig casting malloc using modern (ie C99 which is only 20 years old) does not matter as the implicit declarations are illegal and cause errors – 0___________ May 28 '18 at 00:39

2 Answers2

3

Person * is a pointer to Person type
(Person *) is a C type casting to the pointer to Person type (read up on type-casting if you're unfamiliar)
(* marriage) is dereferencing the marriage pointer, which is basically accessing the variable stored in the memory location pointed to by the pointer. Also a tip, since marriage appears to be a pointer to a struct and you're accessing a member of that struct, you can avoid the (*marriage).male syntax and use the -> operator like this marriage->male

StereoBucket
  • 423
  • 3
  • 9
1

So, the original code was:

Person * father = (Person *) malloc(sizeof(Person));
Marriage * marriage = (Marriage *) malloc(sizeof(Marriage));

1) Let place explicit boundaries between the type and the variable on each line

(Person *) father = (Person *) malloc(sizeof(Person));
(Marriage *) marriage = (Marriage *) malloc(sizeof(Marriage));

You see? So, here we have a type combined with the asterisk and it says a compiler "hey, this guy is a pointer to the type". And we use the same type on the right side to convert very generic (void *) to exact type.

2) It's time to use the thing we allocated. I could say, your original version is not so wide-spread way due excessive syntax (that's confusing you for sure):

(* marriage).male = father;

Way more preferred way is to say the following:

marriage->male = father;

Just 2 chars as the -> instead of prepending and appending all that (* and ). around the variable name. And final result is just the same.

Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42