0

I understand how it works, but I want to know why this function doesn't work when I pass just pointer to head of the list instead of pointer to pointer to head of the list.

This works:

void pushToList(node **listHead, int val) {
    node *temp = malloc(sizeof(node));
    temp->value = val;
    temp->next = *listHead;
    *listHead = temp;
}

This doesn't:

void pushToList(node *listHead, int val) {
    node *temp = malloc(sizeof(node));
    temp->value = val;
    temp->next = listHead;
    listHead = temp;
}

Doesn't it do same thing after dereferencing pointer to pointer ?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Mackovic
  • 37
  • 8
  • Does this answer your question? [What's the difference between passing by reference vs. passing by value?](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) – Joseph Sible-Reinstate Monica May 08 '20 at 19:09

3 Answers3

2

In the second piece of code:

void pushToList(node * listHead, int val) {
    node * temp = malloc(sizeof(node));
    temp->value = val;
    temp->next = listHead;
    listHead = temp;
}

The caller passes a pointer-to-node, called listHead. This pointer is passed by value. For example:

node *myNode;
// ...
pushToList(myNode, 123);

The final line of the function overwrites the local variable listHead, but this does not affect the value of the caller (here myNode). In fact, the value passed to the function might not even be an lvalue: consider an example as follows:

node nn; // stack-allocated
pushToList(&nn, 123); 

The correct solution, which you provide in the first example, is to pass a pointer to the pointer-to-node, so that the push function can update that pointer-to-node.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
1

temp is a pointer
so listHead it's should be i pointer for it, which mean add an extra pointer

like changing a normal int should have pointer
but changing pointer int should have double pointer

0

You are not constrained to use a pointer to pointer.

It has to do more with what of the 2 ways you prefer to write your code. They also have pros and cons.

Now:

void pushToList(node **listHead, int val) {
    node *temp = malloc(sizeof(node));
    temp->value = val;
    temp->next = *listHead;
    *listHead = temp;
}

As you said the above will work.

void pushToList(node *listHead, int val) {
    node *temp = malloc(sizeof(node));
    temp->value = val;
    temp->next = listHead;
    listHead = temp;
}

That won't but the following

node *pushToList(node *listHead, int val) {
    node *temp = malloc(sizeof(node));
    temp->value = val;
    temp->next = listHead;
    
    return temp;
}

will also work.

In the first code you must pass the memory address of the pointer that points to the head of your list, not the memory address of the head of the list. The reason you do that is to have access to the pointer that points to the head of the list and change where it points (to the new node that will be the head)

In the last code you pass the memory address of the current head, not the memory address of the pointer that points to that memory so you can add the new node but the pointer that points to the head of your list remains unchanged so you return the new head and you save it to the pointer who points to the head.

I will post a picture soon of what it happens and they will all become clear.