title: Linked list in c and MALLOC
body: <p>I'm trying to understand the code below, and I'm having some trouble understanding why there's no seg fault when I run it.  I suppose I need to use malloc to allocate the list at the beginning of the main function?  Can someone explain how the memory for the list is allocated?</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  typedef struct DListElmt_ {
  
  void               *data;
  struct DListElmt_  *prev;
  struct DListElmt_  *next;
  
  } DListElmt;
  
  typedef struct DList_ {
  
  int                size;
  
  int                (*match)(const void *key1, const void *key2);
  void               (*destroy)(void *data);
  
  DListElmt          *head;
  DListElmt          *tail;
  
  } DList;
  
  void dlist_init(DList *list, void (*destroy)(void *data));
  
  void dlist_destroy(DList *list);
  
  int dlist_ins_next(DList *list, DListElmt *element, const void *data);
  
  int dlist_ins_prev(DList *list, DListElmt *element, const void *data);
  
  int dlist_remove(DList *list, DListElmt *element, void **data);
  
  #define dlist_size(list) ((list)-&gt;size)
  
  #define dlist_head(list) ((list)-&gt;head)
  
  #define dlist_tail(list) ((list)-&gt;tail)
  
  #define dlist_is_head(element) ((element)-&gt;prev == NULL ? 1 : 0)
  
  #define dlist_is_tail(element) ((element)-&gt;next == NULL ? 1 : 0)
  
  #define dlist_data(element) ((element)-&gt;data)
  
  #define dlist_next(element) ((element)-&gt;next)
  
  #define dlist_prev(element) ((element)-&gt;prev)
  
  void dlist_init(DList *list, void (*destroy)(void *data)) {
      list-&gt;size = 0;
      list-&gt;destroy = destroy;
      list-&gt;head = NULL;
      list-&gt;tail = NULL;
  
  return;
  
  }
  
  void dlist_destroy(DList *list) {
  
      void    *data;
  
      while (dlist_size(list) &gt; 0) {
  
          if (dlist_remove(list, dlist_tail(list), (void **)&amp;data) == 0 &amp;&amp; list-&gt;destroy != NULL) {
  
              list-&gt;destroy(data);
     }
  
  }
  
      memset(list, 0, sizeof(DList));
  
      return;
  }
  
  int dlist_ins_next(DList *list, DListElmt *element, const void *data) {
  
  DListElmt          *new_element;
  
  if (element == NULL &amp;&amp; dlist_size(list) != 0)
     return -1;
  
  if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL)
     return -1;
  new_element-&gt;data = (void *)data;
  
  if (dlist_size(list) == 0) {
     list-&gt;head = new_element;
     list-&gt;head-&gt;prev = NULL;
     list-&gt;head-&gt;next = NULL;
     list-&gt;tail = new_element;
  
     }
  
  else {
     new_element-&gt;next = element-&gt;next;
     new_element-&gt;prev = element;
  
     if (element-&gt;next == NULL)
        list-&gt;tail = new_element;
     else
        element-&gt;next-&gt;prev = new_element;
  
     element-&gt;next = new_element;
  
  }
  list-&gt;size++;
  
  return 0;
  
  }
  
  int dlist_ins_prev(DList *list, DListElmt *element, const void *data) {
  
  DListElmt          *new_element;
  
  if (element == NULL &amp;&amp; dlist_size(list) != 0)
     return -1;
  
  if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL)
     return -1;
  
  new_element-&gt;data = (void *)data;
  
  if (dlist_size(list) == 0) {
     list-&gt;head = new_element;
     list-&gt;head-&gt;prev = NULL;
     list-&gt;head-&gt;next = NULL;
     list-&gt;tail = new_element;
  
     }
  
  
  else {
     new_element-&gt;next = element; 
     new_element-&gt;prev = element-&gt;prev;
  
     if (element-&gt;prev == NULL)
        list-&gt;head = new_element;
     else
        element-&gt;prev-&gt;next = new_element;
  
     element-&gt;prev = new_element;
  
  }
  
  list-&gt;size++;
  
  return 0;
  
  }
  
  int dlist_remove(DList *list, DListElmt *element, void **data) {
  
  if (element == NULL || dlist_size(list) == 0)
     return -1;
  
  *data = element-&gt;data;
  
  if (element == list-&gt;head) {
  
     list-&gt;head = element-&gt;next;
  
     if (list-&gt;head == NULL)
        list-&gt;tail = NULL;
     else
        element-&gt;next-&gt;prev = NULL;
  
     }
  
  else {
     element-&gt;prev-&gt;next = element-&gt;next;
  
     if (element-&gt;next == NULL)
        list-&gt;tail = element-&gt;prev;
     else
        element-&gt;next-&gt;prev = element-&gt;prev;
  
  }
  
  free(element);
  
  list-&gt;size--;
  
  return 0;
  
  }
  
  void print_list(const DList *list) {
  
  DListElmt          *element;
  
  int                *data,
  
  fprintf(stdout, "List size is %d\n", dlist_size(list));
  
  i = 0;
  element = dlist_head(list);
  
  while (1) {
  
     data = dlist_data(element);
     fprintf(stdout, "list[%03d]=%03d\n", i, *data);
  
     i++;
  
     if (dlist_is_tail(element))
        break;
     else
        element = dlist_next(element);
  
  }
  
  return;
  
  }
  
  int main(int argc, char **argv) {
  
  DList              list;
  DListElmt          *element;
  
  int                *data, i;
  
  dlist_init(&amp;list, free);
  
  element = dlist_head(&amp;list);
  
  for (i = 10; i &gt; 0; i--) {
  
     if ((data = (int *)malloc(sizeof(int))) == NULL)
        return 1;
  
     *data = i;
  
     if (dlist_ins_prev(&amp;list, dlist_head(&amp;list), data) != 0)
        return 1;
  
  }
  
  print_list(&amp;list);
  
  element = dlist_head(&amp;list);
  
  for (i = 0; i &lt; 8; i++)
     element = dlist_next(element);
  
  data = dlist_data(element);
  fprintf(stdout, "Removing an element after the one containing %03d\n", *data);
  
  if (dlist_remove(&amp;list, element, (void **)&amp;data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Inserting 011 at the tail of the list\n");
  
  *data = 11;
  if (dlist_ins_next(&amp;list, dlist_tail(&amp;list), data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Removing an element at the tail of the list\n");
  
  element = dlist_tail(&amp;list);
  if (dlist_remove(&amp;list, element, (void **)&amp;data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Inserting 012 just before the tail of the list\n");
  
  *data = 12;
  if (dlist_ins_prev(&amp;list, dlist_tail(&amp;list), data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Iterating and removing the fourth element\n");
  
  element = dlist_head(&amp;list);
  element = dlist_next(element);
  element = dlist_prev(element);
  element = dlist_next(element);
  element = dlist_prev(element);
  element = dlist_next(element);
  element = dlist_next(element);
  element = dlist_next(element);
  
  if (dlist_remove(&amp;list, element, (void **)&amp;data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Inserting 013 before the first element\n");
  
  *data = 13;
  if (dlist_ins_prev(&amp;list, dlist_head(&amp;list), data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Removing an element at the head of the list\n");
  
  if (dlist_remove(&amp;list, dlist_head(&amp;list), (void **)&amp;data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Inserting 014 just after the head of the list\n");
  *data = 14;
  
  if (dlist_ins_next(&amp;list, dlist_head(&amp;list), data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  fprintf(stdout, "Inserting 015 two elements after the head of the list\n");
  
  if ((data = (int *)malloc(sizeof(int))) == NULL)
     return 1;
  
  *data = 15;
  element = dlist_head(&amp;list);
  element = dlist_next(element);
  
  if (dlist_ins_next(&amp;list, element, data) != 0)
     return 1;
  
  print_list(&amp;list);
  
  i = dlist_is_head(dlist_head(&amp;list));
  fprintf(stdout, "Testing dlist_is_head...Value=%d (1=OK)\n", i);
  i = dlist_is_head(dlist_tail(&amp;list));
  fprintf(stdout, "Testing dlist_is_head...Value=%d (0=OK)\n", i);
  i = dlist_is_tail(dlist_tail(&amp;list));
  fprintf(stdout, "Testing dlist_is_tail...Value=%d (1=OK)\n", i);
  i = dlist_is_tail(dlist_head(&amp;list));
  fprintf(stdout, "Testing dlist_is_tail...Value=%d (0=OK)\n", i);
  
  fprintf(stdout, "Destroying the list\n");
  dlist_destroy(&amp;list);
  
  return 0;
  
  }
  </code></pre>
  
  <p>Thanks for the help.</p>