A variable is a named location in memory. That location is where it's value is stored.
A pointer is simply a variable whose value is an address, i.e., it's value is the location of other data.
Dereferencing a pointer causes the pointer's value, an address, to be used to access another location.
A "double pointer" is nothing special at all. It's simply a pointer whose value is the address of another pointer.
Run and study the output of this program. (The (void*) casts are necessary for the proper use of the %p format spec, which prints an address.)
Code:
#include <stdio.h>
void g(int **ppx) {
printf(" g: ppx (%p) = %p *ppx = %p **ppx = %d\n",
(void*)&ppx, (void*)ppx, (void*)*ppx, **ppx);
++**ppx;
printf(" g: ppx (%p) = %p *ppx = %p **ppx = %d\n",
(void*)&ppx, (void*)ppx, (void*)*ppx, **ppx);
}
void f(int *px) {
printf(" f: px (%p) = %p *px = %d\n",
(void*)&px, (void*)px, *px);
++*px;
g(&px);
++*px;
printf(" f: px (%p) = %p *px = %d\n",
(void*)&px, (void*)px, *px);
}
int main(void) {
int x = 1;
printf("main: x (%p) = %d\n", (void*)&x, x);
++x;
f(&x);
++x;
printf("main: x (%p) = %d\n", (void*)&x, x);
return 0;
}
Possible output:
Code:
main: x (0x7fff4f8f407c) = 1
f: px (0x7fff4f8f4058) = 0x7fff4f8f407c *px = 2
g: ppx (0x7fff4f8f4038) = 0x7fff4f8f4058 *ppx = 0x7fff4f8f407c **ppx = 3
g: ppx (0x7fff4f8f4038) = 0x7fff4f8f4058 *ppx = 0x7fff4f8f407c **ppx = 4
f: px (0x7fff4f8f4058) = 0x7fff4f8f407c *px = 5
main: x (0x7fff4f8f407c) = 6