1
#include <assert.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

bool debugOpt=false;

int main (int argc, char **argv) {
   (void) argc;
   char *progname = basename (argv[0]);
   char err_buffer [256];
   char err_buf_fmt[16];

   int option=getopt(argc,argv,"d");
   if(option=='d') debugOpt=true;

   typedef struct node *Node;
   struct node {
      char *item;
      Node link;
   };
   Node head=NULL;

   char buffer[82];
   int ln;
   for(ln=1;;++ln){

      char *line=fgets(buffer,sizeof buffer, stdin);
      if(line==NULL) break;

      char *nlpos=strchr(buffer,'\n');
      if (nlpos!=NULL) *nlpos='\0';
       else{
           fprintf(stderr,"%s: %d: unterminated line: %s\n",
                   progname, ln, buffer);
       }

 Node tmp=malloc(sizeof (struct node));
 assert(tmp != NULL);
 if(tmp!=NULL) tmp->item = strdup (buffer); //leak here

         Node prev=NULL;
         Node curr=head;

           //find insertion point
         while(curr != NULL) {
              int cmp=strcmp(curr->item, tmp->item);
              if(cmp>0) break;
              prev=curr;
              curr=curr->link;
           }
           //do insertion
         tmp->link = curr;
         if (prev==NULL) head =tmp;
         else prev->link = tmp;
   }


//print the list
        Node cursor;
        for(cursor=head;cursor!=NULL;cursor=cursor->link){

         if(debugOpt==true)
             printf("%p -> struct node {item= %.15g, link=%p}\n", cursor, cursor->item, cursor->link);
         else
             printf("%s\n",cursor->item);
             }


      //free nodes
      while(head!=NULL){
          Node oldhead=head;
          head=head->link;
          free(oldhead);
      }


   return EXIT_SUCCESS;
}

basically this program read the lines and then print out in lexicographic order.

I see that the use of strdup(buffer) is causing a leak and I'm not freeing it.

when I put the statement

free(tmp->item)

, it shows that no leaks are possible. But it won't give correct output then. How should I deal with this leak?

Gavin Z.
  • 423
  • 2
  • 6
  • 16

2 Answers2

2

Welcome to the joys of manual memory management. You need to free everything you allocate, and do so exactly once, and after something is freed it must no longer be used. So, insert the free somewhere after you are finished with the string for good. For example, into the loop at the end of your program (before free(oldhead), because you can't use the object pointed to by oldhead after that).

Arkku
  • 41,011
  • 10
  • 62
  • 84
1

You should free the item at the end of your program when you free the linked list:

  while(head!=NULL){
      free(head->item);  /* <-- Free the item here. */
      Node oldhead=head;
      head=head->link;
      free(oldhead);
  }
nwellnhof
  • 32,319
  • 7
  • 89
  • 113