1

I'm making a program to add items to a LIFO (last in first out) array, where the elements are inserted at the start of the array.

Here is my code:

typedef struct neud{
    int num;
    struct neud *next;
}neud;

void add(neud** head,int val){
    //creat a new neod
    neud* newNeod;
    newNeod = malloc(sizeof(neud));
    //assigning
    newNeod->num = val;
    newNeod->next= *head;
    //change the head;
    *head = newNeod;
}

int main()
{
     neud* head = NULL;
     add(&head,10);
     add(&head,20);
     add(&head,30);
     return 0;
}

Everything works fine, but I don't understand precisely the need for a double-pointer here. Can someone explain this?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Alane
  • 13
  • 4
  • The duplicate post explains why a double pointer is needed. – kaylum May 26 '22 at 21:23
  • everything in C is pass-by-value, pointers are no exception. If you want a function to make changes to data that persist outside of it, you must 1) return a value or 2) pass in a pointer to the data so the pointer can be dereferenced inside the function, accessing the data it points to. In this case, the data to change is itself a pointer, so a double pointer is required. – yano May 26 '22 at 21:27

2 Answers2

0

In C all arguments to functions are passed by value. That means the value used in the call is copied into the functions local argument variable.

As such, the argument variable behaves like any other local variable, and its life-time ends with the end of the function. All changes you made to the variable will be lost when the function returns.

Now think about the head pointer. If you don't pass a pointer to a pointer, and just assign to head:

void add(neud* head,int val){
    // ...
    head = newNeod;
}

Now that assignment will be lost.

When you pass a pointer to a pointer, you emulate call by reference. The function now has a pointer to the original pointer. You can dereference the double-pointer head to get the original variable head in the main function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Consider this simple program.

#include <stdio.h>

void f( int x )
{
    x = 10;
}

int main( void )
{
    int x = 0;

    f( x );

    printf( "x = %d\n", x );
}

The program output is

x = 0

That is the function f deals with a copy of the value of the variable x passed to the function. So changing the copy within the function has no effect relative to the original variable x.

To change the original variable x in the function you need to pass it by reference. In C passing by reference means passing an object indirectly through a pointer to it. Thus dereferencing the pointer within the function you get a direct access to the object pointed to by the pointer and can change it.

Compare the program below with this program above

#include <stdio.h>

void f( int *px )
{
    *px = 10;
}

int main( void )
{
    int x = 0;

    f( &x );

    printf( "x = %d\n", x );
}

The program output is

x = 10

So if you will declare your function like

void add(neud * head,int val);

and call it like

add( head, 10 );

then the function will deal with a copy of the value of the original pointer head. The value of the pointer itself will stay unchanged. So you need to pass the pointer by reference that is the function should be declared like

void add(neud** head,int val);

and called like

add( &head, 10 );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335