#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;项目)
,它表明没有泄漏是可能的。但它不会给出正确的输出。我应该如何应对这种泄漏?
答案 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);
}