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

108 Views Asked by At

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

2

There are 2 best solutions below

13
Vlad from Moscow On BEST ANSWER

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
0
Support Ukraine On

Allocate(&p);///whyyyy????

The short answer is: Because you want the function to change the value of p

Further explanation:

In C all function calls uses "pass-by-value" for the function arguments. So if you have:

int x = 42;
some_function(x);

The function some_function will receive the value 42 - just as if your call was some_function(42);. The function knows nothing about the variable x.

A more detailed example:

void foo(int x) {
    printf("%d\n", x);  // Will print 42
    x = 5;
    printf("%d\n", x);  // Will print 5
}

void bar(void) {
    int x = 42;
    printf("%d\n", x);  // Will print 42
    foo(x);
    printf("%d\n", x);  // Will still print 42
}

Even if foo do change x it does not change x inside bar. The x in the two functions are different variables. There is no relation between them. The function foo just received the value 42 and used it to initialize its local variable x but that has nothing to do with x inside bar.

So what do we do in C when we want foo to change the value of x inside bar?

Answer: We pass a pointer to x instead of x

That looks like:

void foo(int* x) {       // Notice all the * in the function.
    printf("%d\n", *x);  // Will print 42
    *x = 5;              // Will change the value of x inside bar
    printf("%d\n", *x);  // Will print 5
}

void bar(void) {
    int x = 42;
    printf("%d\n", x);  // Will print 42
    foo(&x);            // Notice the &
    printf("%d\n", x);  // Will now print 5 as x was changed by foo
}

Now foo receives a pointer to x inside bar. That's the purpose of &x. Using that pointer foo can access x in bar using a dereference of the pointer, i,.e. the *x part.

In your code the principle is just the same. You want Allocate to change the value of p. Consequently, you have to pass &p.