An example of how addresses are stored in memory:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* x = NULL;
printf ("address of new pointer-type variable x: %p\n", &x);
printf ("value of variable x: %p\n", x);
x = (int*) malloc(sizeof(int));
printf ("now pointer-type variable x value exists and it is: %p\n", x);
printf ("address of new pointer-type variable x: %p\n", &x);
return 0;
}
A more complex example from cs50, which we analyzed in detail with the help of comments:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* x = NULL;
int* y = NULL;
printf ("address of new pointer-type variable x: %p\n", &x);
printf ("value of variable x: %p\n", x);
x = (int*) malloc(sizeof(int));
printf ("now pointer-type variable x value exists and it is: %p\n", x);
printf ("Note that address of pointer-type variable x still: %p\n\n", &x);
*x = 42;
printf ("So.. variable x contain address %p.\n", x);
printf ("In bytes which can be found by this address we will write number: %d\n\n", *x);
// now if we will try...
// *y = 13;
// ...we will have CRUSH: cause we try to write a value by address which was not defined;
printf ("address of pointer-type variable y: %p\n", y);
// now we copy value of a pointer-type variable x to y
y = x;
printf ("pointer-type variable y now store address: %p, which has value y: %d\n", y, *y);
// put a number ('13') into allocated space by address which is stored as value in pointer-type variable y
*y = 13;
printf ("pointer-type variable y contain address: %p; value y: %d\n", y, *y);
printf ("x variable still contain the same address: %p, but different value x: %d\n", x, *x);
return 0;
}