2014-02-23 4 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(oldhead) 이전에는 oldhead이 가리키는 개체를 사용할 수 없기 때문에).