Consider the below example,
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int **p; /* A pointer to a pointer to an integer */
int a;

p = malloc(sizeof(int *));

*p = malloc(sizeof(int)); /* OR *p = &a; */

**p = 10;

printf("a = %d **p = %dn", a, **p);
}

Output:

a = 10 **p = 10
In the above example, ‘p’ is a double pointer which means, ‘p’ will point to another pointer which in-turn is pointing to an integer variable.
Now, we have ‘p’ which is a pointer to a pointer. ‘p’ has its memory allocated at some address location say, ‘1000’. Lets say ‘p’ is ponting to another pointer ‘x’ which is at the address ‘1004’. Then ‘x’ in-turn will be pointing to variable ‘a’ located at say, 1008.
Box Diagram representation of pointers

‘p’ points to ‘x’.
‘x’ points to ‘a’
p->x->a or (p->*p->**p)
if say, pointer ‘x’ is not declared, then the second link in the above representation will break.
p->( )->a or (p->( )->**p)
It means, there is no memory representing link-2 which will have the address of ‘a’. Hence, by using dynamic memory allocation, we can first allocate a memory by declaring a pointer variable ‘x’ and make the link.
Or, dynamically allocate a memory of type (int *) and make ‘p’ to directly point to that memory and put the address of ‘a’ in that allocated memory. The above program represents the second case.

In other words,

if you have a double pointer say,

int **p;

It means, at the declaration, memory is allocated for the variable ‘p’ which can point to another integer pointer which in turn will point to an integer variable. i.e., if it is a double pointer, then there needs three memory locations, one for ‘p’ of type ‘int **’ (pointer to a integer pointer) which is allocated during declaration, another for ‘*p’ of type ‘int *’ (pointer to an integer) and the third memory for integer to which it points to (say, an integer value ’10’). So, two memory allocations are needed.

p = malloc(sizeof(int *));

*p = malloc(sizeof(int));

The first statement will allocate the second memory for *p (type: int *) and its address is stored in p (type: int **).

The second statement will allocate the third memory required to store an integer ’10’ (type: int) and its address is stored in *p (type: int *).

The third memory can also be  a integer variable (say, count) in which case, the second statement above can be modified as

*p = &count;

Similarly,

For triple pointer, ***p, there shall be 4 memory locations, 3 for pointers and one for the variable it is pointing to and so on..

But, why do we need a double or a tripple pointer?

Leave a Reply

Your email address will not be published. Required fields are marked *