Pointer to pointer (Linked List)

I don't understand how the push function really works. Why do i need a pointer to pointer? And why doesn't it work without pointer to pointer ? Thank you!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <stdlib.h>

struct node {
    int data;
    struct node * next;
};

/* Given a reference (pointer to pointer) to the head of a list and an int, 
   inserts a new node on the front of the list. */
void push(struct node ** head_ref, int new_data) {
    // 1. allocate node
    struct node * new_node = malloc(sizeof(struct node));
    
    // 2. put in the data
    new_node->data = new_data;
    
    // 3. Make next of new node as head
    new_node->next = *head_ref;
    
    // 4. move the head to point to the new node
    *head_ref = new_node;
}   

void printList(struct node * x) {
    while(x != NULL) {
        printf("%d ", x->data);
        x = x->next;
    }
    printf("\n");
}

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

    push(&head, 16);
    push(&head, 75); 
    push(&head, 3);    
    
    printf("Created Linked list is: ");
    printList(head);
    
    return 0;
}
Last edited on
A function parameter is either by value or by reference.
A by value parameter is a copy made from whatever the calling code calls the function with.
A reference is a reference, not a copy.

Lets start abstract:
1
2
3
4
5
6
7
void foo( T bar, U & gaz );

int main() {
  T x;
  U y;
  foo( x, y );
}

The bar is a by value parameter. The bar is copy constructed from x. It is similar to writing:
T bar = x;
Changing bar within foo will not change the x in main.

Tha gas is a reference to y (during this call to foo). If you do change the gaz in the function, then the value of y will change too.

Same example, with more concrete types:
1
2
3
4
5
6
7
void foo( int * bar, int & gaz );

int main() {
  int * x;
  int y;
  foo( x, y );
}

The bar is a copy. If you do change what the bar points to, the change will not affect the x.

What does confuse you (and many other too) is that the object that the x and bar do point to, can be changed via both pointers. That object is not x.

One more time:
1
2
3
4
5
6
7
8
void foo( int * * bar, int * & gaz );

int main() {
  int z;
  int * x = &z;
  int ** w = &x;
  foo( w, x );
}

Now bar is a copy of w, which is a pointer to x. If you do change the pointed to object (*bar) in the function, then you do change x.
However, the gaz is now a reference to x, so changing gaz has same effect as changing *bar.
Topic archived. No new replies allowed.