Search code examples
cpass-by-referencepass-by-valuepointer-to-pointer

why do I need to add an & sign while allocating a memory space inside a functions?


I wanted to try making an allocate function for a cell in a list, but when using it inside another functions, I need to add an "&" sign

I am aware of what "&" means in c (the address of the variable)but I don't understand why do I need to use it here?

this the allocate function I made

/*1*/void Allocate(struct cell **p) {
  (*p) = malloc(sizeof(struct cell));
}

that's the function i used it in

void Makelist(struct cell **headP, int n){
    struct cell *q;
    struct cell *p;
    int value;
    Allocate(&p);///whyyyy????
    *headP=p;
    Ass_adr(p,NULL);
    printf("\ngive the value on cell 1:");
    scanf("%d",&value);
    Ass_val(p,value);
        for (int i=1; i<n;i++){
            Allocate(&q);
            Ass_adr(q,NULL);
            Ass_adr(p,q);
            printf("give the value in the cell %d:",i+1);
            scanf("%d",&value);
            Ass_val(p,value);
            p=q;
        }
}

I expected to only type

Allocate(p);

yet if I don't add the "&" inside the main program it functions normally


Solution

  • In C passing by reference means passing an object indirectly through a pointer to it. Thus dereferencing the passed pointer you have a direct access to the original object and can change it.

    There is written in the C Standard (6.2.5 Types, p.#20):

    A pointer type may be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called "pointer to T".

    So to change an original object (that in turn can be a pointer) in a function you need to pass a reference to it that is a pointer.

    In this code snippet

    struct cell *p;
    //...
    Allocate(&p);
    

    the pointer p is passed to the funtion Allocate by reference. So the function changes the original passed object (pointer) p

    (*p) = malloc(sizeof(struct cell));
    

    Otherwise if to pass the pointer directly then it will be passed to the function by value. That is the function will deal with a copy of the original pointer and the copy will be changed. The original pointer will stay unchanged.

    Consider the following simple deminstration program:

    #include <stdio.h>
    
    void f( int *p )
    {
        p = NULL;
    }
    
    void g( int **p )
    {
        *p = NULL;
    }
    
    int main( void )
    {
        int x = 10;
    
        int *p = &x;
    
        printf( "Before calling function f() p = % p\n", ( void * )p );
    
        f( p );
    
        printf( "After  calling function f() p = % p\n", ( void * )p );
    
        printf( "Before calling function g() p = % p\n", ( void * )p );
    
        g( &p );
    
        printf( "After  calling function g() p = % p\n", ( void * )p );
    }
    

    The program output might look like

    Before calling function f() p = 00CFF9FC
    After  calling function f() p = 00CFF9FC
    Before calling function g() p = 00CFF9FC
    After  calling function g() p = 00000000