Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why pointer to pointer is needed to allocate memory in function

I have a segmentation fault in the code below, but after I changed it to pointer to pointer, it is fine. Could anybody give me any reason?

void memory(int * p, int size) {
    try {
        p = (int *) malloc(size*sizeof(int));
    } catch( exception& e) {
        cout<<e.what()<<endl;   
    }
}

it does not work in the main function as blow

int *p = 0;
memory(p, 10);

for(int i = 0 ; i < 10; i++)
    p[i] = i;

however, it works like this .

void memory(int ** p, int size) {               `//pointer to pointer`
    try{
        *p = (int *)    malloc(size*sizeof(int));
    } catch( exception& e) {
        cout<<e.what()<<endl;   
    }
}

int main()
{
    int *p = 0;
    memory(&p, 10);       //get the address of the pointer

    for(int i = 0 ; i < 10; i++)
        p[i] = i;

    for(int i = 0 ; i < 10; i++)
        cout<<*(p+i)<<"  ";

    return 0;
}
like image 780
skydoor Avatar asked Apr 12 '10 22:04

skydoor


2 Answers

Because you're wanting to get a pointer value back from the operations done in the function. malloc allocates memory and gives you an address for that memory.

In your first example, you store that address in the local argument variable p, but since it's just the argument, that doesn't make it back to the main program, because C/C++ are pass-by-value by default - even for pointers.

Main      Function      malloc

  p         p            allocated
+---+     +---+         
| 0 |     | 0 |           A
+---+     +---+

becomes...

  p         p            allocated
+---+     +---+         
| 0 |     | ------------> A
+---+     +---+

and thus when main reads p, it gets 0, not A.

In your working code, you follow the pointer passed to an address, and that address gives you the location of the pointer variable in the main program. You update the pointer value at that address, which the main program can then look up the value of to use as its memory location - thus passing the address returned by malloc back to the main program for use.

Main      Function      malloc

  p         p            allocated    
+---+     +---+         
| 0 |<------- |           A
|   |     |   |
+---+     +---+

becomes...

  p         p            allocated    
+---+     +---+         
|   |<------- |           
| ----------------------> A
+---+     +---+

and thus when main reads p, it gets A.

like image 178
Amber Avatar answered Oct 08 '22 02:10

Amber


A pointer stores the address at which the data is stored. Passing a pointer to a function means giving it the address of the data. However, here you have no address for the data until calling malloc. So instead you need to pass the address of the pointer (i.e. pointer to pointer). This allows memory to take the address of the pointer p and set p to point to the area of memory it allocates for the data.

like image 20
Arkku Avatar answered Oct 08 '22 02:10

Arkku