2014-02-23 71 views
0
#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導致的泄漏?

我看到使用strdup(緩衝區)導致泄漏,我沒有釋放它。

當我把聲明

免費(TMP->項)

,它表明沒有泄漏是可能的。但它不會給出正確的輸出。我應該如何處理這個泄漏?

回答

1

當你釋放鏈表你應該在你的程序結束釋放item

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

歡迎來到手動內存管理的樂趣。您需要free您分配的所有內容,並且一次執行一次,並且釋放某些內容後,不得再使用它。所以,在之後插入free某處您已經完成了該字符串。例如,在程序結束時的循環中(在free(oldhead)之前,因爲您不能使用oldhead指向的對象)。