-2

Before this is marked as a dup, I have read
In C, what does a variable declaration with two asterisks (**) mean?
I don't understand the implementation of inserting a new node in linked list
And I still am struggling with the logical steps of the double asterisk. I understand that in a linked list I need to create a new node, dynamically allocate space for it and then relabel the new node as the head.
I just don't understand the logical steps of the function between the &head and the double asterisk. What is pointing to what and how does the implementation of the double asterisk work here?

void push(struct node** head_ref, int new_data)
{
    struct node* new_node = (struct node*)malloc(sizeof(struct node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

push(&head, 2);
  • 7
    Use pen and paper. Execute the code by hand. Draw pictures. Write the value of variables. – klutt Feb 18 '18 at 17:10
  • That doesn't look like a standard `push` function - it's more like a `createAndPush` – fredrik Feb 18 '18 at 17:10
  • 1. Takes in the address as a pointer to a pointer (Because it's a node) 2. Creates 2nd node 3. Makes the new node point to the (old) head 4. Then relabels the new_node as head (Or whatever the 1st item is in list) So the double asterisk is just a double asterisk because of the nature of the struct of the node? Like struct node ** is basically declaring the type of node and datatype? – Nathan Cheng Feb 18 '18 at 17:14
  • Function calls work like assignments: The arguments are assigned to the parameters. We have `head_ref = &head`, so `head_ref` is pointing to `head`. – melpomene Feb 18 '18 at 17:18
  • @klutt Yeah actually pen and paper worked out for me. Ty – Nathan Cheng Feb 18 '18 at 17:34

2 Answers2

0

Since the caller passes &head as the first argument,

  • head_ref is equal to &head
  • *head_ref is equal to head.

The call push(&head, 2) therefore has the same net effect as writing code in the caller as follows.

/*   struct node **head_ref = &head;   */

struct node *new_node = malloc(sizeof(struct node));
new_node->data = 2;
new_node->next = head;       /*   new_node = (*head_ref) */
head = new_node;             /*    (*head_ref) = new_node */

I've commented out all usage of head_ref since that is a variable local to the function, and not seen by the caller. The comments in the last two statements show the equivalence.

Note that I've also removed the type conversion of the result from malloc(), as such a thing is generally considered poor practice in C.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • Thanks I actually realize now that it has to be double asterisk in order to get at the address and have it take in an address. I thought that there were some logical steps that I was missing in that it was pointing to something unknown in preparation for the new node (Which was not created yet!) Now I see thank you all – Nathan Cheng Feb 18 '18 at 17:33
0

Indeed, in order to understand what is going on you have to understand what pointer to pointer is as well as meaning of deference operator *. Then you can follow the code:

void push(struct node** head_ref, int new_data)

Function push has two arguments: a pointer to a pointer and int value.

head is a pointer to a variable of type struct node

struct node* head;

To properly call push you have to take the address of the head pointer. It is done by use of & operator. Then &head is the address of the pointer.

struct node **head_ref = &head;

sg7
  • 6,108
  • 2
  • 32
  • 40