# TL;DR

Your code provokes Undefined Behavior, as already mentioned in Morlacke’s Answer. Other than that, it seems that you’re having problems on understanding how pointers work. See references for tutorials.

When you say that there’s memory allocated for `ip` in this case:

``````int i = 10;
int *ip;
ip = &i;
``````

What happens is:

1. You declare an `int` variable called `i` and assign the value `10` to it. Here, the computer allocates memory for this variable on the stack. Say, at address `0x1000`. So now, address `0x1000` has content `10`.
2. Then you declare a pointer called `ip`, having type `int`. The computer allocates memory for the pointer. (This is important, see bellow for explanation). Your pointer is at address, say, `0x2000`.
3. When you assign `ip = &i`, you’re assigning the address of variable `i` to variable `ip`. Now the value of variable `ip` (your pointer) is the address of `i`. `ip` doesn’t hold the value `10``i` does. Think of this assignment as `ip = 0x1000` (don’t actually write this code).
4. To get the value `10` using your pointer you’d have to do `*ip` – this is called dereferencing the pointer. When you do that, the computer will access the contents of the address held by the pointer, in this case, the computer will access the contents on the address of `i`, which is `10`. Think of it as: `get the contents of address 0x1000`.

Memory looks like this after that snippet of code:

``````VALUE    :   10    | 0x1000 |
VARIABLE :    i    |   ip   |
ADDRESS  :  0x1000 | 0x2000 |
``````

## Pointers

Pointers are a special type of variable in C. You can think of pointers as typed variables that hold addresses. The space your computer allocates on the stack for pointers depends on your architecture – on `32bit` machines, pointers will take 4 bytes; on `64bit` machines pointers will take 8 bytes. That’s the only memory your computer allocates for your pointers (enough room to store an address).

However, pointers hold memory addresses, so you can make it point to some block of memory… Like memory blocks returned from malloc.

So, with this in mind, lets see your code:

``````NODE *hi;
printf("\nbefore malloc\n");
``````
1. Declare a pointer to `NODE` called `hi`. Lets imagine this variable `hi` has address `0x1000`, and the contents of that address are arbitrary – you didn’t initialize it, so it can be anything from zeroes to a ThunderCat.
2. Then, when you print `hi` in your `printf` you’re printing the contents of that address `0x1000`… But you don’t know what’s in there… It could be anything.
3. Then you dereference the `hi` variable. You tell the computer: access the contents of the ThunderCat and print the value of variable `next`. Now, I don’t know if ThunderCats have variables inside of them, nor if they like to be accessed… so this is Undefined Behavior. And it’s bad!

To fix that:

``````NODE *hi = malloc(sizeof NODE);
printf("&hi: %p\n", &hi);
printf(" hi: %p\n", hi);
``````

Now you have a memory block of the size of your structure to hold some data. However, you still didn’t initialize it, so accessing the contents of it is still undefined behavior.

To initialize it, you may do:

``````hi->id = 10;
hi->next = hi;
``````

And now you may print anything you want. See this:

``````#include <stdio.h>
#include <stdlib.h>

struct node {
int id;
struct node *next;
};

typedef struct node NODE;

int main(void)
{
NODE *hi = malloc(sizeof(NODE));

if (!hi) return 0;

hi->id = 10;
hi->next = hi;

printf("Address of hi (&hi)   : %p\n", &hi);
printf("Contents of hi        : %p\n", hi);
printf("Contents of next      : %p\n", hi->next);
printf("Address of id         : %p\n", &(hi->id));
printf("Contents of id        : %d\n", hi->id);

free(hi);

return 0;
}
``````

And the output:

``````\$ ./draft
Address of hi (&hi)   : 0x7fffc463cb78
Contents of hi        : 0x125b010
Contents of next      : 0x125b010
Contents of id        : 10
``````

The address of variable `hi` is one, and the address to which it points to is another. There are several things to notice on this output:

1. `hi` is on the stack. The block to which it points is on the heap.
2. The address of `id` is the same as the memory block (that’s because it’s the first element of the structure).
3. The address of `next` is 8 bytes from `id`, when it should be only 4(after all `int`s are only 4 bytes long) – this is due to memory alignment.
4. The contents of `next` is the same block pointed by `hi`.
5. The amount of memory “alloced” for the `hi` pointer itself is 8 bytes, as I’m working on a `64bit`. That’s all the room it has and needs.
6. Always `free` after a `malloc`. Avoid memory leaks
7. Never write code like this for other purposes than learning.

Note: When I say “memory alloced for the pointer” I mean the space the computer separates for it on the stack when the declaration happens after the Stack Frame setup.

## References

solved Why the address of structure and next is not same?