I am writing a program that is sorting the lines from the input text file. It does its job, however I get memory leaks using 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;
}
Any ideas where they might come from? I loop over all_lines[] and free the content, then free all_lines itself.
UPDATE:
Ok, so I've done the updates you have suggested. However, now valgrind throws error for functions fprintf in my program. Here is what it says:
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)
I would like to know why it reports error on simply fprintf those lines to a text file. I've looked up that it is something concerning gcc optimalization turning fprint into fputs but I dont get this idea
There are multiple problems in your code:
function
getline
:line
buffer is not properly'\0'
terminated at the end of thedo / while
loop.free
theline
buffer upon end of file, hence memory leak.'\n'
.malloc
notrealloc
return values are checked for memory allocation failure.realloc
theline
to the actual size used to reduce the amount of memory consumed. Currently, you allocate at least 1024 bytes per line. Sorting the dictionary will require 100 times more memory than needed!function
MyCompare
:The lines read include the
'\n'
at the end. Comparison may yield unexpected results:"Hello\tworld\n"
will come before"Hello\n"
. You should strip the'\n'
ingetline
and modify theprintf
formats appropriately.function
main
:fopen
, invoking undefined behaviourfree
the lines returned bygetline
... big memory leak!rewind
ed. If your program is given its input via a pipe,rewind
will fail except for very small input sizes.all_lines
array as you read the lines in a single loop.Printing the lines before sort is not very useful and complicates testing.