title: When should you free memory dynamically allocated?
body: <p>Essentially, I have created a piece of Code which consists of a tree, whereby each tree node has its own linked list containing data, (each treeNode containing data as well). So that each  treeNode can have multiple data items for that specific treeNode.</p>
  
  <p>For this structure therefore to be created, I calloc a treenode, pass the address of that treenode to a createListNode function, and calloc a ListNode. My confusion stems really from, where exactly should I be freeing memory? Merely at the end of the program before return 0; in main, or elsewhere. Baring in mind once all the input is added to the tree and list, it then asks the user for a name, and displays the linked list of data appropriate for that name.</p>
  
  <p>Cheers.</p>
  
  <p>T.C. </p>
  
  <p>EDIT: </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;ctype.h&gt;
  #include &lt;string.h&gt;
  
  typedef struct ListNode {
      char            *number;
      struct ListNode *next;
  }ListNode;
  
  typedef struct TreeNode {
      char            *name;
      ListNode        *numbers;
      struct TreeNode *left;
      struct TreeNode *right;
  }TreeNode;
  
  TreeNode* AddNode(TreeNode *, char *, char *);
  void  AddNum(TreeNode *, char *);
  void N_Print(TreeNode* root);
  TreeNode* SearchTree(TreeNode* root, char *search);
  
  int main(void) {
  char my_string[50], name[25], number[25];
  TreeNode *root = NULL;
  while ((fgets(my_string, 50, stdin)) != NULL) {
          if (my_string[0] == '.')
              break;      
      sscanf(my_string, "%s %s", name, number); 
      root = AddNode(root, name, number);  
  }   
  N_Print(root);
  free(root);
  free(root-&gt;numbers);
  return 0;
  }
  
  TreeNode* AddNode(TreeNode *root, char *name, char *number) {
  int comparison;   
  if (root == NULL) {
      root = (TreeNode*)calloc(1,sizeof(TreeNode));
      root-&gt;name = strdup(name); 
      root-&gt;left = root-&gt;right = NULL;      
      AddNum(root, number);
  }else if ((comparison = strcasecmp(name, root-&gt;name)) &lt; 0)
      root-&gt;left = AddNode(root-&gt;left, name, number);
  else if ((comparison = strcasecmp(name, root-&gt;name)) &gt; 0) {
      root-&gt;right = AddNode(root-&gt;right, name, number);
  } else if ((comparison = strcasecmp(name, root-&gt;name)) == 0 ) {
      AddNum(root, number);
  }       
  return root;
  }
  
  void AddNum(TreeNode *tn, char *number) {
   ListNode *ln = (ListNode *)calloc(1, sizeof(ListNode));
   ln-&gt;number = strdup(number);
   ln-&gt;next = tn-&gt;numbers;
   tn-&gt;numbers = ln;
  }
  
  TreeNode* SearchTree(TreeNode* root, char *search) {
  int comparison;
  if (root == NULL) {
      return NULL;
  } else if ((comparison = strcasecmp(search, root-&gt;name)) == 0) {
      return root;
  } else if ((comparison = strcasecmp(search, root-&gt;name)) &lt; 0) {
       return SearchTree(root-&gt;left, search);
  } else if ((comparison = strcasecmp(search, root-&gt;name)) &gt; 0) 
       return SearchTree(root-&gt;right, search);    
  }
  
  void N_Print(TreeNode* root) {
  TreeNode* search_val;
  char search[25];
  while(1) {
      printf("Type a name please: ");
      scanf("%24s", search);
              if (search[0] == '.')
                      break;
      search_val = SearchTree(root, search); 
      if (search_val == NULL) {
          printf("NOT FOUND\n");
          continue;
      }
      ListNode* ln = search_val-&gt;numbers;
      while ( ln != NULL) {
              printf("%s\n", ln-&gt;number);
              ln = ln-&gt;next;
      }
  }
  }
  </code></pre>