如何解决由strdup引起的泄漏?

时间:2014-02-23 23:41:21

标签: c memory memory-leaks strdup

#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;
}

基本上这个程序读取行,然后按字典顺序打印出来。

我看到使用strdup(缓冲区)导致泄漏,我不会释放它。

当我发表声明时

  

自由(TMP-&GT;项目)

,它表明没有泄漏是可能的。但它不会给出正确的输出。我应该如何应对这种泄漏?

2 个答案:

答案 0 :(得分:2)

欢迎来到手动内存管理的乐趣。您需要free分配的所有内容,并且完全一次,并且在释放某些内容后,必须再次使用它。所以,在之后插入free某处你完成了字符串。例如,进入程序末尾的循环(free(oldhead)之前,因为在此之后你无法使用oldhead指向的对象。)

答案 1 :(得分:1)

当您释放链接列表时,您应该在程序结束时释放item

  while(head!=NULL){
      free(head->item);  /* <-- Free the item here. */
      Node oldhead=head;
      head=head->link;
      free(oldhead);
  }