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

struct node
{
  int val;
  struct node* next; /* This is not a node, just an adress-variable happening to point to a node */
};

/*  'list' keep the adress of the variable holding the start of the list
 *  '*list' is that variable, keeping the adress (pointing to) a node
 *  '**list' would be the actual node
 *  '(**list).val' would be the nodes values
 *  '(*list)->val' would be the more common way of writing the above
 *
 * We need the double pointer in order to be able to modify the value
 * of the start-of-the list variable. I C++ we would have used a
 * reference instead:
 *  void prepend(struct node*& list, int val)
 */
void prepend(struct node** list, int val)
{
  /* We need malloc since a local variable would go out of scope and
   * the memory is reclaimed at the end of our function.  When we want
   * to keep the variable indefinitely (until we decide to free it) we
   * need to allocate memory for it using malloc and keep track of the
   * adress returned from malloc until we called free on it.
   */
  struct node* n = malloc(sizeof(struct node));
  n->val = val;
  n->next = *list;
  *list = n;
}

int main()
{
  struct node* list = NULL;

  prepend(&list, 1);
  prepend(&list, 2);
  prepend(&list, 3);
  prepend(&list, 4);

  struct node* curr = list;
  while ( curr != NULL )
  {
    printf("%d\n", curr->val);
    printf("%d\n", (*curr).val);
    curr = curr->next;
  }

  curr = list;
  while ( curr != NULL )
  {
    /* We can not free the memory right away since we want to read
     * curr->next at the next line, thus me must save the adress of
     * the node to delete */
    struct node* victim = curr;
    curr = curr->next;
    
    /* Now we are done accessing the meory that will be deallocated. */
    free(victim);
  }
}