title: leaking memory while reading a file to doubly linked list
body: <p>Please consider this code I was tinkering with, it reads a file and loads into a doubly linked list:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  
  struct Node{
          char * data;
          struct Node *Next;
          struct Node *Prev;
  };
  
  struct Doubly_Linked_List{
          struct Node *headNode;
          struct Node *tailNode;
          int LLSize;
  };
  
  void InsertAtEnd(struct Doubly_Linked_List *myll, char* data );
  void reBalance(struct Doubly_Linked_List *myll);
  void PrintLL(struct Doubly_Linked_List *myll);
  void append( struct Doubly_Linked_List *myll, char* data);
  
  void PrintLL(struct Doubly_Linked_List *myll){
          struct Node *Node = myll-&gt;headNode;
          int i = 0;
          while (Node){
          //printf("Node is likely at %ld\n", Node-&gt;data);
                  printf("Index: %d has : %s", i, Node-&gt;data);
                  i++;
                  Node = Node-&gt;Next;
          }
  
  }
  
  void reBalance(struct Doubly_Linked_List *myll){
          printf("Rebalancing myll\n");
          struct Node *Node = myll-&gt;headNode;
          struct Node *LastNode;
          int i = 0;
          while (Node){
                  LastNode = Node;
                  i++;
                  Node = Node-&gt;Next;
          }
          myll-&gt;LLSize = i;
          myll-&gt;tailNode = LastNode;
  }
  
  
  void append( struct Doubly_Linked_List *myll, char* data){
          if (!myll-&gt;headNode){
          printf("Inserting at start\n");
                  struct Node *NewHeadNode = malloc( sizeof(*NewHeadNode) ) ;
                  NewHeadNode-&gt;data = malloc( strlen(data) * sizeof(char)  );
                  strcpy(NewHeadNode-&gt;data, data);
                  NewHeadNode-&gt;Prev = NULL;
                  NewHeadNode-&gt;Next = NULL;
                  myll-&gt;headNode = NewHeadNode;
          } else {
          printf("Inserting at end\n");
                  InsertAtEnd(myll, data);
          }
  }
  
  
  void InsertAtEnd(struct Doubly_Linked_List *myll, char* data ){
          //printf("%s was evoked\n", __func__);
          reBalance(myll);
          struct Node *Node = myll-&gt;tailNode;
          struct Node *NewTailNode = malloc( sizeof(*NewTailNode) );
          NewTailNode-&gt;data = malloc( strlen(data) *sizeof(char) );
          strcpy(NewTailNode-&gt;data, data);
          NewTailNode-&gt;Next = NULL;
          NewTailNode-&gt;Prev = Node;
          Node-&gt;Next = NewTailNode;
          reBalance(myll);
  }
  
  
  
  void FreeMem(struct Doubly_Linked_List *myll){
          //printf("%s was evoked\n", __func__);
          reBalance(myll);
          int i = 0;
          struct Node *Node = myll-&gt;headNode;
          while (Node){
          struct Node *NextNode = Node-&gt;Next;
                  //printf("Freeing Node at Index: %d with data : %s\n", i, Node-&gt;data);
          free(Node);
                  i++;
                  Node = NextNode;
          }
      free(myll);
  }
  
  int main(){
  
      char *filename = "/proc/net/dev";
      struct Doubly_Linked_List *myll = malloc(sizeof(myll));
  
      FILE *fp = fopen(filename,"r");
      if (!fp){
          printf("Error!\n");
          return 0;
      }
  
      char filetext[400];
      while (fgets(filetext, 400, fp) ){
          append(myll, filetext);
          PrintLL(myll);
          printf("myll-&gt;LLSize: %d\n", myll-&gt;LLSize);
      }
  
      fclose(fp);
      FreeMem(myll);
      return 0;
  }
  </code></pre>
  
  <p>It works OK, as in, it enumerates and prints the linked list, and this looks like the file it was asked to read.</p>
  
  <p>However, valgrind seems to indicate I have a memory leak:</p>
  
  <pre><code>==7755== 77 bytes in 1 blocks are definitely lost in loss record 1 of 2
  ==7755==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==7755==    by 0x1089FE: append (stack_overflow.c:53)
  ==7755==    by 0x108BF7: main (stack_overflow.c:108)
  ==7755== 
  ==7755== 494 bytes in 4 blocks are definitely lost in loss record 2 of 2
  ==7755==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==7755==    by 0x108AAF: InsertAtEnd (stack_overflow.c:70)
  ==7755==    by 0x108A62: append (stack_overflow.c:60)
  ==7755==    by 0x108BF7: main (stack_overflow.c:108)
  ==7755== 
  ==7755== LEAK SUMMARY:
  ==7755==    definitely lost: 571 bytes in 5 blocks
  ==7755==    indirectly lost: 0 bytes in 0 blocks
  ==7755==      possibly lost: 0 bytes in 0 blocks
  ==7755==    still reachable: 0 bytes in 0 blocks
  ==7755==         suppressed: 0 bytes in 0 blocks
  ==7755==
  </code></pre>
  
  <p>After burning hours into it, it still is leaking - 571 bytes is the best I could leak. I must be doing something I am oblivious to, and would like another set of eyes and tutelage. Thanks!</p>
  
  <p><strong>Update: 1</strong></p>
  
  <p>Thanks! I made a few changes based on the responses and suggestions : switched to calloc, and made sure to free up the text data I was reading from the file. </p>
  
  <p>Happy to report valgrind checks passes this:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  
  struct Node{
          char * data;
          struct Node *Next;
          struct Node *Prev;
  };
  
  struct Doubly_Linked_List{
          struct Node *headNode;
          struct Node *tailNode;
          int LLSize;
  };
  
  void PrintLL(struct Doubly_Linked_List *myll);
  void append( struct Doubly_Linked_List *myll, char* data);
  
  void PrintLL(struct Doubly_Linked_List *myll){
          //printf("%s was evoked\n", __func__);
          struct Node *Node = myll-&gt;headNode;
          int i = 0;
          while (Node){
          //printf("Node is likely at %ld\n", Node-&gt;data);
                  printf("Index: %d has : %s", i, Node-&gt;data);
                  i++;
                  Node = Node-&gt;Next;
          }
      printf("-----------------------------\n");
  
  }
  
  void Freemem(struct Doubly_Linked_List *myll){
      struct Node *Node = myll-&gt;headNode;
      while (Node){
          struct Node *Next = Node-&gt;Next;
  
          free(Node-&gt;data);
          free(Node);
          Node = Next;
      }
      free(myll);
  }
  
  
  void append( struct Doubly_Linked_List *myll, char* data){
          if (!myll-&gt;LLSize){
          printf("Inserting at start\n");
                  struct Node *NewHeadNode = calloc(5, sizeof(*NewHeadNode) ) ;
                  NewHeadNode-&gt;data = calloc( 1,( strlen(data) +2) );
                  strcpy(NewHeadNode-&gt;data, data);
                  myll-&gt;headNode = NewHeadNode;
                  myll-&gt;tailNode = NewHeadNode;
          myll-&gt;LLSize = 1;
          } else {
          //printf("Inserting at end\n");
          struct Node *OldTail =  myll-&gt;tailNode;
          struct Node *NewTailNode = calloc(1, sizeof(*NewTailNode) );
          NewTailNode-&gt;data = calloc( 1,( strlen(data) +2) );
                  strcpy(NewTailNode-&gt;data, data);
  
          // wire the pointers
          OldTail-&gt;Next = NewTailNode;
          NewTailNode-&gt;Prev = OldTail;
          NewTailNode-&gt;Next = NULL;
  
          // adjust our size
          myll-&gt;LLSize++;
  
          // set new tail node:
                  myll-&gt;tailNode = NewTailNode;;
          }
  }
  
  
  int main(){
  
      char *nic = "wlp4s0";
      char *filename = "/proc/net/dev";
  
      struct Doubly_Linked_List *myll = calloc(10,sizeof(myll));
  
      FILE *fp = fopen(filename,"r");
      if (!fp){
          Freemem(myll);
          perror("Error!\n");
          return 1;
      }
  
      char filetext[400];
      while (fgets(filetext, 400, fp) ){
          append(myll, filetext);
          PrintLL(myll);
          printf("myll-&gt;LLSize: %d\n", myll-&gt;LLSize);
      }
      fclose(fp);
  
      Freemem(myll);
      return 0;
  }
  </code></pre>