我正在编写一个程序,用于对输入文本文件中的行进行排序。它完成了它的工作,但是我使用valgrind得到了内存泄漏。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getline(FILE * infile)
{
int size = 1024;
char * line = (char*)malloc(size);
int temp;
int i=0;
do
{
(temp = fgetc(infile));
if (temp !=EOF)
line[i++]=(char)temp;
if (i>=size)
{
size*=2;
line = (char*)realloc(line, size);
}
}while (temp != '\n' && temp !=EOF);
if (temp==EOF)
return NULL;
return line;
}
void print_line (char * line)
{
printf("%s", line);
}
int myCompare (const void * a, const void * b )
{
const char *pa = *(const char**)a;
const char *pb = *(const char**)b;
return strcmp(pa,pb);
}
int main (int argc, char* argv[])
{
FILE * infile;
FILE * outfile;
infile = fopen(argv[1], "r");
if (infile==NULL)
{
printf("Error");
exit(3);
}
outfile = fopen(argv[2], "w");
if (outfile==NULL)
{
printf("Error");
exit(3);
}
char * line;
char **all_lines;
int nlines=0;
while((line=getline(infile))!=NULL)
{
print_line(line);
nlines++;
}
all_lines=malloc(nlines*sizeof(char*));
rewind(infile);
int j=0;
printf("%d\n\n", nlines);
while((line=getline(infile))!=NULL)
{
all_lines[j]=line;
j++;
}
qsort(all_lines, nlines, sizeof(char*), myCompare);
for (int i=0; i<nlines;i++)
{
print_line(all_lines[i]);
fprintf(outfile, "%s", all_lines[i]);
}
for(int i =0; i<nlines;i++)
{
free(all_lines[i]);
}
free(all_lines);
fclose(infile);
fclose(outfile);
return 0;
}
他们可能来自哪些想法?我遍历all_lines []并释放内容,然后释放all_lines本身。
更新:
好的,我已经完成了你建议的更新。但是,现在valgrind在我的程序中抛出函数fprintf的错误。以下是它的说法:
11 errors in context 2 of 2:
==3646== Conditional jump or move depends on uninitialised value(s)
==3646== at 0x40BA4B1: vfprintf (vfprintf.c:1601)
==3646== by 0x40C0F7F: printf (printf.c:35)
==3646== by 0x80487B8: print_line (sort_lines.c:44)
==3646== by 0x804887D: main (sort_lines.c:77)
==3646== Uninitialised value was created by a heap allocation
==3646== at 0x4024D12: realloc (vg_replace_malloc.c:476)
==3646== by 0x8048766: getline (sort_lines.c:30)
==3646== by 0x804889A: main (sort_lines.c:75)
我想知道为什么它只是简单地将这些行报告给文本文件。我已经抬头看到这是关于gcc优化的问题,将fprint转化为fput但我不明白这个想法
答案 0 :(得分:1)
您的代码中存在多个问题:
功能getline
:
line
缓冲区中的字符串在'\0'
循环结束时未正确do / while
终止。free
line
缓冲区,因此内存泄漏。'\n'
结尾,则不会在文件末尾返回部分行。malloc
而不是realloc
返回值是否存在内存分配失败。realloc
line
到用于减少内存消耗量的实际大小。目前,每行至少分配1024个字节。对字典进行排序将需要 100倍更多的内存! 功能MyCompare
:
读取的行包括最后的'\n'
。比较可能会产生意外结果:"Hello\tworld\n"
将在"Hello\n"
之前出现。您应该删除'\n'
中的getline
并正确修改printf
格式。
功能main
:
fopen
打开命令行参数之前,不检查是否实际提供了命令行参数,从而调用未定义的行为free
getline
返回的行... 大内存泄漏!rewind
。如果您的程序通过管道输入,rewind
将失败,除非输入尺寸非常小。all_lines
数组。在排序之前打印线条不是很有用,并使测试复杂化。