-1
struct node
{
   int data;
   struct node *link;
};

struct node *addnode(struct node **head);

int main()
{
    struct node *head = NULL;

    addnode(&head);

    return 0;
}


struct node *addnode(struct node **ptrTohead)
{
       if (*ptrTohead == NULL)
       {
          struct node *newNode = (struct node*) malloc(sizeof(struct node));
          *ptrTohead = newNode;
       }

}

i am making a linked list implementation in C and came across this code: what i do not understand is how &head is of type struct node ** after all *head is a pointer that stores an address, and &head gets the address of the head variable. So how is that a pointer to pointer?

This is how i imagine it:

//                head ----> |___2______| 
/memory address/  100           200
// &head is 100 and is of type struct node *

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 4
    `head` is a `struct node*` and taking the address of `head` gets you the pointer to a `struct node*` which is a `struct node**` (there must be a duplicate to this?) – Ted Lyngmo Aug 03 '21 at 23:12
  • 3
    You just described how you have a pointer, and you took a pointer to it. How is that not a pointer to a pointer? – hobbs Aug 03 '21 at 23:17
  • 1
    "`*head` is a pointer" ... No, `head` is a pointer. `*head` dereferences that pointer (and is of type `struct node`). The address of a pointer is a pointer to a pointer. – jamesdlin Aug 03 '21 at 23:18
  • so basically taking the address of ```head```, gives the address of a pointer (```head```) and ```head``` points to something hence joining these two ideas together means it is a struct node**? am i thinking of this correctly its so confusing lol – programmerc3981143 Aug 03 '21 at 23:18
  • 1
    Yes. For any type `T`, pointer to `T` is `T*`. pointer to `T*` is `T**`. – stark Aug 03 '21 at 23:30
  • The `*` has a different meaning, depending on where it is written. In a declaration, it means "pointer". However, outside a declaration, it is the dereference operator, which is used to dereference pointers. – Andreas Wenzel Aug 03 '21 at 23:35
  • The name reuse of `head` between the prototype and `main` probably didn't do you any favors. Hyper focus on the types. – WhozCraig Aug 03 '21 at 23:37
  • but what i dont get is that *head is a pointer that stores a address, right? a pointer to pointer is essentially a pointer variable that holds the address of another pointer variable. All *head does is store the address of a struct NOT another pointer. so if that is the case &head should give us the address of the pointer known as head, so how on earth is this a pointer to a pointer then? – programmerc3981143 Aug 03 '21 at 23:49
  • As has been stated several times in the comments, "\*head is a pointer that stores a address" is *not* correct. – William Pursell Aug 03 '21 at 23:56

2 Answers2

0

Investigate this simple demonstrative program.

#include <stdio.h>

int main(void) 
{
    int x = 10;
    
    int *p = &x;

    printf( "The variable x stores the value %d\n", x );
    printf( "Its address is %p\n", ( void * )&x );
    
    printf( "\nThe pointer p stores the address of the variable x %p\n", 
            ( void * )p );
    printf( "Dereferencing the pointer p we will get x equal to %d\n" , *p );
    printf( "The address of the pointer p itself is %p\n", ( void * )&p );
    
    int **pp = &p;
    
    printf( "\nThe pointer pp stores the address of the pointer p %p\n", 
            ( void * )pp );
    printf( "Dereferencing the pointer pp we will get the address stored in p %p\n",
            ( void * )*pp );
    printf( "Dereferencing the pointer pp two times "
            "we will get  x equal to %d\n", **pp );

    int y = 20;
    
    printf( "\nBecause dereferencing the pointer pp\n"
            "we have a direct access to the value stored in p\n"
            "we can change the value of p\n" );

    *pp = &y;           

    printf( "\nNow the pointer p stores the address of the variable y %p\n", 
            ( void * )p );
    printf( "Dereferencing the pointer p we will get y equal to %d\n" , *p );
    printf( "The address of the pointer p itself was not changed %p\n", ( void * )&p );
    
    return 0;
}

The program output might look like

The variable x stores the value 10
Its address is 0x7fffd5f6de90

The pointer p stores the address of the variable x 0x7fffd5f6de90
Dereferencing the pointer p we will get x equal to 10
The address of the pointer p itself is 0x7fffd5f6de98

The pointer pp stores the address of the pointer p 0x7fffd5f6de98
Dereferencing the pointer pp we will get the address stored in p 0x7fffd5f6de90
Dereferencing the pointer pp two times we will get  x equal to 10

Because dereferencing the pointer pp
we have a direct access to the value stored in p
we can change the value of p

Now the pointer p stores the address of the variable y 0x7fffd5f6de94
Dereferencing the pointer p we will get y equal to 20
The address of the pointer p itself was not changed 0x7fffd5f6de98

That is the variables p and pp are both pointers. The difference is that the pointer p points to an object of the type int (to the variable x or y) while the pointer pp points to the variable p that has the type int *. Dereferencing any of these pointers you will get a direct access to the pointed object and can change it (if it is not a constant object).

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

In main, head is a pointer to struct node. The expression &head is the address of a pointer to struct node. ptrTohead is the formal parameter of the function addnode and is a pointer to pointer to struct node. The value of &head can be assigned to ptrTohead because it is the address of a pointer to struct node, and the address of a pointer to struct node is an appropriate value with which to initialize a pointer to pointer to struct node.

Note that &head is not a pointer to pointer to struct node. It is the address of a pointer to struct node. Also note that *head is not a pointer. *head is a struct node, while head is a pointer to struct node.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • if ```&head``` isnt a pointer to pointer why does it have type ```struct node **```, is it because each level of the expression ```&head``` has a seperate value and putting them together gives ```struct node**```? by *level* i mean the depth of the addresses in this expression. So ```&head``` gives the address of the pointer which is 1 level of type ```struct node *```, then de-referencing this gives another address of type ```struct node*```. Those two types added together give ```struct node**```. Well thats how i think of it at least how correct is this @WilliamPursell – programmerc3981143 Aug 05 '21 at 15:44
  • This is probably semantic quibbling. The expression `&head` evaluates to the address of a pointer to struct node. A variable of type `struct node **` can be assigned a value which is the address of a pointer to struct node. – William Pursell Aug 05 '21 at 15:48
  • Ah ok i see but would the way i think of it suffice or is this incorrect? – programmerc3981143 Aug 05 '21 at 15:49
  • 1
    I don't know what you mean by "depth of the addresses". I find it easier to always think of `T *h` meaning that h is a pointer to T. So `&h` is the address of a pointer to T. Whether `T` is an `int` or a `struct foo ***` is irrelevant. – William Pursell Aug 05 '21 at 15:52