Search code examples
cpointersstructoperatorsdereference

What is the difference between ptr->thing and *ptr->thing in C?


My understanding is that the -> operator is shorthand for dereferencing a pointer to a struct, and accessing the value of one struct member.

struct point {
   int x;
   int y;
};
struct point my_point = { 3, 7 };
struct point *p = &my_point;  /* p is a pointer to my_point */
(*p).x = 8;                   /* set the first member of the struct */
p->x = 8;                     /* equivalent method to set the first member of the struct */

So the last 2 lines of the example above are equivalent. But I've encountered some code similar to this:

*p->x = 8

Using both the asterisk and arrow together. What does this do? Would this try to "double dereference" the pointer and assign to memory address 8, or something else? Maybe undefined behavior, or just a compiler error?


Solution

  • *p->x is equivalent to *(p->x) - you are dereferencing the result of p->x, which implies the x member itself has pointer type. Given a line like

    *p->x = 8;
    

    that implies x has type int *:

    struct foo {
      ...
      int *x;
      ...
    };
    

    Note that x must be assigned a valid pointer value before you can assign to *x. You can allocate memory dynamically:

    struct foo *p = malloc( sizeof *p ); // dynamically allocate space for 1 instance of struct foo
    if ( !p )
      // handle allocation failure and exit here.
    
    p->x = malloc( sizeof *p->x ); // dynamically allocate space for 1 int.
    if ( !p->x )
      // handle allocation failure and exit here.
    

    Or you can set x to point to an existing int object:

    int a;
    ...
    p->x = &a;
    *p->x = 8;