title: How to find out the cause of an "Invalid Free()" error inside valgrind report
body: <p>I wrote an xml editor which compiles fine without warning or errors and run without memory leaks. However i keep getting this error <code>Invalid Free()</code> when i run valgrind and i can't figure out what's causing it.</p>
  
  <p>I thought that it could be related to running the <code>free</code> command on a null or freed pointer but i couldn't point it out? what's causing it and how do i tell from the report?</p>
  
  <p>(here's my full code, sorry it's a bit long)</p>
  
  <h2>xml.h</h2>
  
  <pre><code>#ifndef _XML_header
  
  #define MAX 10
  
  xmlDoc *doc;
  xmlNode *root;
  int count;
  char *cursor;
  struct child
  {
      const xmlChar *grandfather;
      const xmlChar *father;
      const xmlChar *name;
      xmlNode *node;
  };
  struct spouse
  {
      const xmlChar *husband;
      const xmlChar *name;
      struct child **children;
      xmlNode *node;
  };
  struct special
  {
      const xmlChar *name;
      const xmlChar *value;
      const xmlChar *details;
      xmlNode *node;
  };
  struct selectedNode
  {
      const xmlChar *name;
      const xmlChar *father;
      const xmlChar *grandfather;
      struct spouse **spouses;
      struct special **specialItems;
      struct spouse *selectedSpouse;
      struct special *selectedSpecialItem;
      xmlNode *node;
  };
  struct child **cont;
  struct selectedNode *selected;
  void check(int condition);
  
  #endif
  </code></pre>
  
  <hr>
  
  <h2>xml.c</h2>
  
  <pre><code>#include &lt;libxml2/libxml/parser.h&gt;
  #include &lt;libxml2/libxml/tree.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;ctype.h&gt;
  #include "xml.h"
  
  xmlNode *getParent(xmlNode *node)
  {
      xmlNode *cur = node-&gt;parent;
      while (cur != NULL)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "child"))
              return cur;
          cur = cur-&gt;parent;
      }
      return NULL;
  }
  
  const xmlChar *getContent(xmlNode *node, const xmlChar *type)
  {
      xmlNode *cur;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, type))
              return xmlNodeListGetString(doc, cur-&gt;xmlChildrenNode, 1);
      }
      return (const xmlChar *) "none";
  }
  
  const xmlChar *getName(xmlNode *node)
  {
      return getContent(node, (const xmlChar *) "name");
  }
  
  const xmlChar *getGender(xmlNode *node)
  {
      return getContent(node, (const xmlChar *) "gender");
  }
  
  const xmlChar *getBirthdate(xmlNode *node)
  {
      return getContent(node, (const xmlChar *) "born");
  }
  
  const xmlChar *getDeathdate(xmlNode *node)
  {
      return getContent(node, (const xmlChar *) "died");
  }
  
  int setContent(xmlNode *node, const xmlChar *nodeName, const xmlChar *content)
  {
      xmlNode *cur;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, nodeName))
          {
              xmlNodeSetContent(cur, content);
              return 0;
          }
      }
      return 1;
  }
  
  int setName(xmlNode *node, const xmlChar *name)
  {
      return setContent(node, (const xmlChar *) "name", name);
  }
  
  int setGender(xmlNode *node, const xmlChar *gender)
  {
      return setContent(node, (const xmlChar *) "gender", gender);
  }
  
  int setBirthdate(xmlNode *node, const xmlChar *born)
  {
      return setContent(node, (const xmlChar *) "born", born);
  }
  
  int setDeathdate(xmlNode *node, const xmlChar *died)
  {
      return setContent(node, (const xmlChar *) "died", died);
  }
  
  struct child *getChild(xmlNode *node, const xmlChar *father, const xmlChar *grandfather)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "child"));
      struct child *temp = calloc(1, sizeof(struct child));
      temp-&gt;father = father;
      temp-&gt;grandfather = grandfather;
      temp-&gt;name = getName(node);
      temp-&gt;node = node;
      return temp;
  }
  
  struct child **getChildren(xmlNode *node, const xmlChar *father, const xmlChar *grandfather)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "spouse"));
      xmlNode  *cur;
      int i = 0;
      struct child **childrenCont = NULL;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "children"))
          {
              if (!cur-&gt;children) return NULL;
              childrenCont = calloc(1, sizeof(struct child *));
              childrenCont[0] = NULL;
              for (cur = cur-&gt;children; cur != NULL; cur = cur-&gt;next)
              {
                  if (cur-&gt;type == XML_ELEMENT_NODE)
                  {
                      childrenCont = realloc(childrenCont, (i + 2) * sizeof(struct child *));
                      childrenCont[i] = getChild(cur, father, grandfather);
                      childrenCont[i + 1] = NULL;
                      i++;
                  }
              }
              break;
          }
      }
      return childrenCont;
  }
  
  struct spouse *getSpouse(xmlNode *node, const xmlChar *husband, const xmlChar *fatherinlaw)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "spouse"));
      struct spouse *temp = calloc(1, sizeof(struct spouse));
      temp-&gt;name = getName(node);
      temp-&gt;children = getChildren(node, husband, fatherinlaw);
      temp-&gt;husband = husband;
      temp-&gt;node = node;
      return temp;
  }
  
  
  struct spouse **getSpouses(xmlNode *node, const xmlChar *husband, const xmlChar *fatherinlaw)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "child"));
      xmlNode *cur;
      int i = 0;
      struct spouse **spousesCont = NULL;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "spouses"))
          {
              if (!cur-&gt;children) return NULL;
              spousesCont = calloc(1, sizeof(struct spouse *));
              spousesCont[0] = NULL;
              for (cur = cur-&gt;children; cur != NULL; cur = cur-&gt;next)
              {
                  if (cur-&gt;type == XML_ELEMENT_NODE)
                  {
                      spousesCont = realloc(spousesCont, (i + 2) * sizeof(struct spouse *));
                      spousesCont[i] = getSpouse(cur, husband, fatherinlaw);
                      spousesCont[i + 1] = NULL;
                      i++;
                  }
              }
              break;
          }
      }
      return spousesCont;
  }
  
  struct special *getSpecialItem(xmlNode *node)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "item"));
      struct special *temp = calloc(1, sizeof(struct special));
      xmlNode *cur;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE)
          {
              if (!xmlStrcmp(cur-&gt;name, (const xmlChar *) "name"))
                  temp-&gt;name = xmlNodeListGetString(doc, cur-&gt;xmlChildrenNode, 1);
              else if (!xmlStrcmp(cur-&gt;name, (const xmlChar *) "value"))
                  temp-&gt;value = xmlNodeListGetString(doc, cur-&gt;xmlChildrenNode, 1);
              else if (!xmlStrcmp(cur-&gt;name, (const xmlChar *) "details"))
                  temp-&gt;details = xmlNodeListGetString(doc, cur-&gt;xmlChildrenNode, 1);
          }
      }
      temp-&gt;node = node;
      return temp;
  }
  
  struct special **getSpecial(xmlNode *node)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "child"));
      xmlNode *cur;
      int i = 0;
      struct special **specialCont = calloc(1, sizeof(struct special *));
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "special"))
          {
              for (cur = cur-&gt;children; cur != NULL; cur = cur-&gt;next)
              {
                  if (cur-&gt;type == XML_ELEMENT_NODE)
                  {
                      specialCont = realloc(specialCont, (i + 2) * sizeof(struct special *));
                      specialCont[i] = getSpecialItem(cur);
                      specialCont[i + 1] = NULL;
                      i++;
                  }
              }
              break;
          }
      }
      return specialCont;
  }
  
  void addChild(xmlNode *node, const xmlChar *name, const xmlChar *born, const xmlChar *died)
  {
      check(xmlStrcmp(node-&gt;name, (const xmlChar *) "spouse"));
      xmlNode *cur;
      xmlNode *childrenCont = NULL;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "children"))
              childrenCont = cur;
      }
      if (childrenCont == NULL) childrenCont = xmlNewChild(node, NULL, (const xmlChar *) "children", NULL);
      xmlNewChild(childrenCont, NULL, (const xmlChar *) "name", name);
      xmlNewChild(childrenCont, NULL, (const xmlChar *) "born", born);
      xmlNewChild(childrenCont, NULL, (const xmlChar *) "died", died);
      xmlNewChild(childrenCont, NULL, (const xmlChar *) "spouses", NULL);
      xmlNewChild(childrenCont, NULL, (const xmlChar *) "special", NULL);
  }
  
  void addSpouse(xmlNode *node, const xmlChar *name, const xmlChar *born, const xmlChar *died)
  {
      check(xmlStrcmp(node-&gt;name, (const xmlChar *) "child"));
      xmlNode *cur;
      xmlNode *spousesCont = NULL;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "spouses"))
              spousesCont = cur;
      }
      if (spousesCont == NULL) spousesCont = xmlNewChild(node, NULL, (const xmlChar *) "spouses", NULL);
      xmlNewChild(spousesCont, NULL, (const xmlChar *) "name", name);
      xmlNewChild(spousesCont, NULL, (const xmlChar *) "born", born);
      xmlNewChild(spousesCont, NULL, (const xmlChar *) "died", died);
      xmlNewChild(spousesCont, NULL, (const xmlChar *) "children", NULL);
      xmlNewChild(spousesCont, NULL, (const xmlChar *) "special", NULL);
  }
  
  void addSpecial(xmlNode *node, const xmlChar *name, const xmlChar *value, const xmlChar *details)
  {
      check(!xmlStrcmp(node-&gt;name, (const xmlChar *) "child"));
      xmlNode *cur;
      xmlNode *specialCont = NULL;
      for (cur = node-&gt;children; cur != NULL; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE &amp;&amp; !xmlStrcmp(cur-&gt;name, (const xmlChar *) "special"))
              specialCont = cur;
      }
      if (specialCont == NULL) specialCont = xmlNewChild(node, NULL, (const xmlChar *) "special", NULL);
      xmlNewChild(specialCont, NULL, (const xmlChar *) "name", name);
      xmlNewChild(specialCont, NULL, (const xmlChar *) "value", value);
      xmlNewChild(specialCont, NULL, (const xmlChar *) "details", details);
  }
  
  void deleteNode(xmlNode *node)
  {
      xmlUnlinkNode(node);
      xmlFreeNode(node);
  }
  
  void printResults()
  {
      int i = 0;
      while (cont[i] != NULL)
      {
          printf("%d- %s son of %s son of %s\n", i + 1,
                 cont[i]-&gt;name, cont[i]-&gt;father, cont[i]-&gt;grandfather);
          i++;
      }
  }
  
  void freeChild(struct child *node)
  {
      if (node == NULL) return;
      xmlFree((xmlChar *) node-&gt;father);
      xmlFree((xmlChar *) node-&gt;grandfather);
      xmlFree((xmlChar *) node-&gt;name);
      free(node);
  }
  
  void freeChildrenCont(struct child **childrenCont)
  {
      int i = 0;
      if (childrenCont == NULL) return;
      while (childrenCont[i] != NULL)
      {
          freeChild(childrenCont[i]);
          i++;
      }
      free(childrenCont);
  }
  
  void freeSpouse(struct spouse *node)
  {
      if (node == NULL) return;
      if (node-&gt;children) freeChildrenCont(node-&gt;children);
      xmlFree((xmlChar *) node-&gt;husband);
      xmlFree((xmlChar *) node-&gt;name);
      free(node);
  }
  
  void freeSpousesCont(struct spouse **spousesCont)
  {
      int i = 0;
      if (spousesCont == NULL) return;
      while (spousesCont[i] != NULL)
      {
          freeSpouse(spousesCont[i]);
          i++;
      }
      free(spousesCont);
  }
  
  void freeSpecial(struct special *item)
  {
      if (item == NULL) return;
      xmlFree((xmlChar *) item-&gt;name);
      xmlFree((xmlChar *) item-&gt;value);
      xmlFree((xmlChar *) item-&gt;details);
      free(item);
  }
  
  void freeSpecialCont(struct special **specialCont)
  {
      int i = 0;
      if (specialCont == NULL) return;
      while (specialCont[i] != NULL)
      {
          freeSpecial(specialCont[i]);
          i++;
      }
      free(specialCont);
  }
  
  void freeCont()
  {
      freeChildrenCont(cont);
  }
  
  void resetCont()
  {
      if (cont != NULL)
      {
          int i = 0;
          while (cont[i] != NULL)
          {
              freeChild(cont[i]);
              i++;
          }
          memset(cont, 0, MAX * sizeof(struct cont *));
      }
      count = 0;
  }
  
  void freeSelected()
  {
      if (selected == NULL) return;
      if (selected-&gt;father) xmlFree((xmlChar *) selected-&gt;father);
      if (selected-&gt;grandfather) xmlFree((xmlChar *) selected-&gt;grandfather);
      if (selected-&gt;name) xmlFree((xmlChar *) selected-&gt;name);
      if (selected-&gt;spouses) freeSpousesCont(selected-&gt;spouses);
      if (selected-&gt;specialItems) freeSpecialCont(selected-&gt;specialItems);
      if (selected-&gt;selectedSpouse) freeSpouse(selected-&gt;selectedSpouse);
      if (selected-&gt;selectedSpecialItem) freeSpecial(selected-&gt;selectedSpecialItem);
      free(selected); 
      selected = NULL;
  }
  
  int getOption()
  {
      char input[20];
      int n = 0;
      if (fgets(input, sizeof(input), stdin)) sscanf(input, "%d", &amp;n);
      return n;
  }
  
  void capitalize(char word[])
  {
      if (isalpha(word[0])) word[0] = toupper(word[0]);
  }
  
  void printSpouses()
  {
      int i = 0;
      if (selected)
      {
          printf("Wives:\n");
          if (selected-&gt;spouses == NULL) printf("\tnone\n");
          else
          {
              if (selected-&gt;spouses[i] == NULL) printf("\tnone\n");
              while (selected-&gt;spouses[i] != NULL)
              {
                  printf("\t %d. %s\n", i + 1, selected-&gt;spouses[i]-&gt;name);
                  i++;
              }
          }
      }
  }
  
  void printChildren(struct spouse *node)
  {
      int i = 0;
      if (selected)
      {
          printf("Children:\n");
          if (node-&gt;children == NULL) printf("\tnone\n");
          else
          {
              if (node-&gt;children[i] == NULL) printf("\tnone\n");
              while (node-&gt;children[i] != NULL)
              {
                  printf("\t%d. %s\n", i + 1, node-&gt;children[i]-&gt;name);
                  i++;
              }
          }
      }
  }
  
  void printSpecialItem(struct special *item, int n)
  {
      if (n) printf("Item:\n");
      else printf("Item %d:\n", n);
      printf("\tName: %s\n", item-&gt;name);
      printf("\tValue: %s\n", item-&gt;value);
      printf("\tDetails: %s\n", item-&gt;details);
  }
  
  void printSpecial()
  {
      int i = 0;
      if (selected == NULL) printf("Must select node first\n");
      else if (selected-&gt;specialItems == NULL || selected-&gt;specialItems[0] == NULL)
          printf("Special:\n\tNo special items found\n");
      else
      {
          printf("special:\n");
          while (selected-&gt;specialItems[i] != NULL)
          {
              printSpecialItem(selected-&gt;specialItems[i], i + 1);
              i++;
          }
      }
  }
  
  void die()
  {
      freeSelected();
      freeCont();
      free(cursor);
      xmlFreeDoc(doc);
      xmlCleanupParser();
  }
  
  void check(int condition)
  {
      if (!condition)
      {
          printf("check failed\n");
          die();
          exit(1);
      }
  }
  
  void showInfo()
  {
      int i = 0;
      const xmlChar *born, *died, *gender;
      if (selected)
      {
          printf("Name: %s\n", selected-&gt;name);
          printf("Father: %s\n", selected-&gt;father);
          printf("Grandfather: %s\n", selected-&gt;grandfather);
          printf("Born: %s\n", (born = getBirthdate(selected-&gt;node)));
          printf("Died: %s\n", (died = getDeathdate(selected-&gt;node)));
          printf("Gender: %s\n", (gender = getGender(selected-&gt;node)));
          printSpouses();
          if (selected-&gt;spouses != NULL &amp;&amp; selected-&gt;spouses[0] != NULL)
          {
              for (i = 0; selected-&gt;spouses[i] != NULL; i++)
              {
                  printChildren(selected-&gt;spouses[i]);
              }
          }
          else printf("Children:\n\tnone\n");
          xmlFree((xmlChar *) born);
          xmlFree((xmlChar *) died);
          xmlFree((xmlChar *) gender);
      }
      else printf("Must select node first\n");
  }
  
  int find(xmlNode *node, const xmlChar *key, const xmlChar *grandfather, const xmlChar *father)
  {
      const xmlChar *name;
      xmlNode *cur;
  
      for (cur = node; cur != NULL &amp;&amp; count &lt; MAX; cur = cur-&gt;next)
      {
          if (cur-&gt;type == XML_ELEMENT_NODE)
          {
              if (!xmlStrcmp(cur-&gt;name, (const xmlChar *) "child"))
              {
                  name = getName(cur);
                  if (!xmlStrcmp(name, key))
                  {
                      cont[count] = malloc(sizeof(struct child));
                      cont[count]-&gt;grandfather = xmlStrdup(grandfather);
                      cont[count]-&gt;father = xmlStrdup(father);
                      cont[count]-&gt;name = xmlStrdup(name);
                      cont[count]-&gt;node = cur;
                      count++;
                  }
                  if (cur-&gt;children) find(cur-&gt;children, key, name, father);
                  xmlFree((xmlChar *) name);
              }
              else if (cur-&gt;children)
                  find(cur-&gt;children, key, father, grandfather);
          }
      }
      return (count &gt; 0) ? 1 : 0;
  }
  
  void selectNode(struct child *node, const char *type, int option)
  {
      xmlNode *cur;
      if (selected == NULL &amp;&amp; strcmp(type, "node"))
      {
          printf("Must select a node first\n");
      }
      else if (!strcmp(type, "node"))
      {
          freeSelected();
          selected = calloc(1, sizeof(struct selectedNode)); 
          selected-&gt;name = xmlStrdup(node-&gt;name);
          selected-&gt;father = xmlStrdup(node-&gt;father);
          selected-&gt;grandfather = xmlStrdup(node-&gt;grandfather);
          selected-&gt;node = node-&gt;node;
          selected-&gt;spouses = getSpouses(selected-&gt;node, selected-&gt;father, selected-&gt;grandfather);
          selected-&gt;specialItems = getSpecial(selected-&gt;node);
          selected-&gt;selectedSpouse = NULL;
          selected-&gt;selectedSpecialItem = NULL;
          memset(cursor, 0, strlen(cursor));
          strcpy(cursor, (char *) node-&gt;name);
          cursor = strcat(cursor, " &gt; ");
      }
      else if (!strcmp(type, "spouse"))
      {
          selected-&gt;selectedSpouse = selected-&gt;spouses[option];
          memset(cursor, 0, strlen(cursor));
          cursor = (char *) selected-&gt;name;
          cursor = strcat(cursor, ":");
          cursor = strcat(cursor, (char *) selected-&gt;selectedSpouse-&gt;name);
          cursor = strcat(cursor, " &gt; ");
      }
      else if (!strcmp(type, "special"))
      {
          selected-&gt;selectedSpecialItem = selected-&gt;specialItems[option];
          memset(cursor, 0, strlen(cursor));
          strcpy(cursor, (char *) selected-&gt;name);
          cursor = strcat(cursor, "[");
          cursor = strcat(cursor, (char *) selected-&gt;selectedSpecialItem-&gt;name);
          cursor = strcat(cursor, "] &gt; ");
      }
      else if (!strcmp(type, "child"))
      {
          if (selected-&gt;selectedSpouse != NULL)
              selectNode(selected-&gt;selectedSpouse-&gt;children[option], (const char *) "node", -1);
          else printf("Spouse is not selected\n");
      }
      else if (!strcmp(type, "father"))
      {
          cur = getParent(selected-&gt;node);
          check(!xmlStrcmp(getName(cur), selected-&gt;father));
          if (cur)
          {
              selected-&gt;name = selected-&gt;father;
              selected-&gt;father = selected-&gt;grandfather;
              selected-&gt;node = cur;
              selected-&gt;spouses = getSpouses(cur, selected-&gt;name, selected-&gt;father);
              selected-&gt;specialItems = getSpecial(cur);
              selected-&gt;selectedSpouse = NULL;
              selected-&gt;selectedSpecialItem = NULL;
              cur = getParent(cur);
              if (cur) selected-&gt;grandfather = getName(cur);
              memset(cursor, 0, strlen(cursor));
              strcpy(cursor, (char *) selected-&gt;name);
              cursor = strcat(cursor, " &gt; ");
          }
          else printf("Parent node was not found\n");
      }
      else printf("Unrecognized option %s", (char *) type);
  }
  
  void execute(char command[], char value[], char option[])
  {
      int rv = 0;
      int n = 0;
      const xmlChar *none = (const xmlChar *) "none";
      if (!strcmp(command, "find"))
      {
          capitalize(value);
          if (value[0] == '\0') printf("Invalid search value\n");
          else if ((rv = find(root, (const xmlChar *) value, none, none)) == 1)
          {
              printf("Found:\n");
              printResults();
              printf("Choose a Person's (number) to select, or (0) to cancel &gt; ");
              if ((n = getOption()) &gt; 0 &amp;&amp; n - 1 &lt; MAX &amp;&amp; cont[n - 1] != NULL)
              {
                  selectNode(cont[n - 1], (const char *) "node", -1);
              }
              resetCont();
          }
          else printf("Nothing found for %s.\n", value);
      }
      else if (!strcmp(command, "info")) showInfo();
      else if (!strcmp(command, "list"))
      {
          if (selected == NULL) printf("Must select a node first\n");
          else
          {
              if (!strcmp(value, "spouses")) printSpouses();
              else if (!strcmp(value, "children"))
              {
                  if (selected-&gt;selectedSpouse != NULL) printChildren(selected-&gt;selectedSpouse);
                  else printf("Must select a spouse first\n");
              }
              else if (!strcmp(value, "special")) printSpecial();
              else printf("Invalid command\n");
  
          }
      }
      else printf("Invalid command\n");
  }
  
  int main(int argc, char *argv[])
  {
      LIBXML_TEST_VERSION
      if (argc &lt; 2)
      {
          printf("Usage: xml filename.xml\n");
          return 1;
      }
  
      char input[40];
      char command[40];
      char value[40];
      char option[40];
      cursor = malloc(100 * sizeof(char));
      strcpy(cursor, "&gt; ");
      count = 0;
      cont = calloc(MAX, sizeof(struct child*));
      selected = NULL;
  
      if ((doc = xmlReadFile(argv[1], NULL, 0)) == NULL)
      {
          printf("error: could not parse file %s\n", argv[1]);
          exit(-1);
      }
      root = xmlDocGetRootElement(doc);
      while(1)
      {
          command[0] = '\0';
          value[0] = '\0';
          option[0] = '\0';
          printf("%s", cursor);
          if (fgets(input, sizeof(input), stdin)) sscanf(input, "%s %s %s", command, value, option);
          if (!strcmp(command, "exit")) break;
  
          execute(command, value, option);
      }
      die();
      return 0;
  }
  </code></pre>
  
  <h2>valgrind</h2>
  
  <pre><code>valgrind --leak-check=full --track-origins=yes -v ./xml data.xml
  .....(some valgrind initializing output).....
  &gt; find luke
  --16891-- REDIR: 0x4238b60 (__GI_memchr) redirected to 0x402e7d0 (__GI_memchr)
  --16891-- REDIR: 0x42397e0 (__GI_memcpy) redirected to 0x402f090 (__GI_memcpy)
  --16891-- REDIR: 0x423b490 (__GI___rawmemchr) redirected to 0x4030ea0 (__GI___rawmemchr)
  Found:
  1- Luke son of Mike son of John
  2- Luke son of John son of none
  Choose a Person's (number) to select, or (0) to cancel &gt; 2
  --16891-- REDIR: 0x42e8cc0 (__memset_sse2) redirected to 0x4030820 (memset)
  Luke &gt; find john
  Found:
  1- John son of none son of none
  Choose a Person's (number) to select, or (0) to cancel &gt; 1
  John &gt; find mike
  Found:
  1- Mike son of John son of none
  Choose a Person's (number) to select, or (0) to cancel &gt; 1
  ==16891== Invalid free() / delete / delete[] / realloc()
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x80490D7: freeChild (xml.c:286)
  ==16891==    by 0x8049132: freeChildrenCont (xml.c:298)
  ==16891==    by 0x804916A: freeSpouse (xml.c:307)
  ==16891==    by 0x80491C2: freeSpousesCont (xml.c:319)
  ==16891==    by 0x804939C: freeSelected (xml.c:372)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891==  Address 0x440f770 is 0 bytes inside a block of size 5 free'd
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x804935F: freeSelected (xml.c:369)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891== 
  ==16891== Invalid free() / delete / delete[] / realloc()
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x80490E2: freeChild (xml.c:287)
  ==16891==    by 0x8049132: freeChildrenCont (xml.c:298)
  ==16891==    by 0x804916A: freeSpouse (xml.c:307)
  ==16891==    by 0x80491C2: freeSpousesCont (xml.c:319)
  ==16891==    by 0x804939C: freeSelected (xml.c:372)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891==  Address 0x440f7a8 is 0 bytes inside a block of size 5 free'd
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x8049374: freeSelected (xml.c:370)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891== 
  ==16891== Invalid free() / delete / delete[] / realloc()
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x8049175: freeSpouse (xml.c:308)
  ==16891==    by 0x80491C2: freeSpousesCont (xml.c:319)
  ==16891==    by 0x804939C: freeSelected (xml.c:372)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891==  Address 0x440f770 is 0 bytes inside a block of size 5 free'd
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x804935F: freeSelected (xml.c:369)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891== 
  Mike &gt; exit
  ==16891== 
  ==16891== HEAP SUMMARY:
  ==16891==     in use at exit: 0 bytes in 0 blocks
  ==16891==   total heap usage: 566 allocs, 590 frees, 68,257 bytes allocated
  ==16891== 
  ==16891== All heap blocks were freed -- no leaks are possible
  ==16891== 
  ==16891== ERROR SUMMARY: 24 errors from 3 contexts (suppressed: 0 from 0)
  ==16891== 
  ==16891== 2 errors in context 1 of 3:
  ==16891== Invalid free() / delete / delete[] / realloc()
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x8049175: freeSpouse (xml.c:308)
  ==16891==    by 0x80491C2: freeSpousesCont (xml.c:319)
  ==16891==    by 0x804939C: freeSelected (xml.c:372)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891==  Address 0x440f770 is 0 bytes inside a block of size 5 free'd
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x804935F: freeSelected (xml.c:369)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891== 
  ==16891== 
  ==16891== 11 errors in context 2 of 3:
  ==16891== Invalid free() / delete / delete[] / realloc()
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x80490E2: freeChild (xml.c:287)
  ==16891==    by 0x8049132: freeChildrenCont (xml.c:298)
  ==16891==    by 0x804916A: freeSpouse (xml.c:307)
  ==16891==    by 0x80491C2: freeSpousesCont (xml.c:319)
  ==16891==    by 0x804939C: freeSelected (xml.c:372)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891==  Address 0x440f7a8 is 0 bytes inside a block of size 5 free'd
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x8049374: freeSelected (xml.c:370)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891== 
  ==16891== 
  ==16891== 11 errors in context 3 of 3:
  ==16891== Invalid free() / delete / delete[] / realloc()
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x80490D7: freeChild (xml.c:286)
  ==16891==    by 0x8049132: freeChildrenCont (xml.c:298)
  ==16891==    by 0x804916A: freeSpouse (xml.c:307)
  ==16891==    by 0x80491C2: freeSpousesCont (xml.c:319)
  ==16891==    by 0x804939C: freeSelected (xml.c:372)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891==  Address 0x440f770 is 0 bytes inside a block of size 5 free'd
  ==16891==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
  ==16891==    by 0x804935F: freeSelected (xml.c:369)
  ==16891==    by 0x804A3DB: selectNode (xml.c:544)
  ==16891==    by 0x804A98F: execute (xml.c:622)
  ==16891==    by 0x8048BEA: main (xml.c:706)
  ==16891== 
  ==16891== ERROR SUMMARY: 24 errors from 3 contexts (suppressed: 0 from 0)
  </code></pre>