I have written a code for an rpn calculator which takes input from a file.
The code seems to work with my test cases but Valgrind tells me there are 28 errors. I am new to C and I haven't used Valgrind much. I can't understand what these errors are. Can someone please help me understand what they are and how to fix them?
There is no memory leakage.
This is my code, sorry for the very messy code.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
float rpn (char * filename)
{
float result;
FILE *in = fopen(filename, "r");
if (in == NULL)
{
fprintf(stderr," input file fopen fail\n");
return EXIT_FAILURE; // if fopen fails, return false
}
int count=0;
char c;
for (c = getc(in); c != EOF && c!='\n'; c = getc(in))
{
if(c==' ')
{
count = count + 1;
}
}
fclose(in);
if (count==0)
{
fprintf(stderr,"EMPTY FILE\n");
fclose(in);
return EXIT_SUCCESS;
}
fprintf(stderr,"count=%d\n",count);
FILE *in2 = fopen(filename, "r");
if (in == NULL)
{
fprintf(stderr," input file fopen fail\n");
return EXIT_FAILURE; // if fopen fails, return false
}
int num = 0;
int num_op = 0;
int index =0;
int len = count+1;
fprintf(stderr,"len = %d\n",len);
char**input = malloc(sizeof(char*)*(len+1));
for(int i =0;i<len; i++)
{
input[i] = malloc(sizeof(char));
fscanf(in2,"%s",input[i]);
if((strcmp(input[i],"+")==0)||(strcmp(input[i],"-")==0)||(strcmp(input[i],"*")==0)||(strcmp(input[i],"/")==0))
{
num_op = num_op + 1;
}
else if(atof(input[i])||(strcmp(input[i],"0")==0)||(strcmp(input[i],"-0")==0))
{
index = index+1;
num = num+1;
}
}
fclose(in2);
fprintf(stderr,"numbers= %d\n",num);
fprintf(stderr,"num_op= %d\n",num_op);
fprintf(stderr,"index= %d\n",index);
if((num != (num_op+1)))
{
fprintf(stderr,"Bad Input\n");
return EXIT_FAILURE;
}
for (int f=index;f<len;f++)
{
if(!((strcmp(input[f],"+")==0)||(strcmp(input[f],"-")==0)||(strcmp(input[f],"*")==0)||(strcmp(input[f],"/")==0)))
{
fprintf(stderr,"Bad Input\n");
return EXIT_FAILURE;
}
}
float *stack = malloc(sizeof(float)*(index+1));
for(int h=0; h<index; h++)
{
stack[h] = atof(input[h]);
}
/* for(int l =0;(l<index); l++)
{
printf("stack[%d] = %lf\n",l,stack[l]);
}
for(int j =0;(j<len); j++)
{
printf("input[%d] = %s\n",j,input[j]);
}
*/
int u = index-1;
for(int k=index;k<len;k++)
{
if ((strcmp(input[k],"+"))==0)
{
stack[u-1] = (stack[u-1] + stack[u]);
printf("Result + = %lf\n",stack[u-1]);
}
else if ((strcmp(input[k],"-"))==0)
{
stack[u-1] = (stack[u-1] - stack[u]);
printf("Result - = %lf\n",stack[u-1]);
}
else if ((strcmp(input[k],"*"))==0)
{
stack[u-1] = (stack[u-1] * stack[u]);
printf("Result * = %lf\n",stack[u-1]);
}
else if ((strcmp(input[k],"/"))==0)
{
stack[u-1] = (stack[u-1] / stack[u]);
printf("Result / = %lf\n",stack[u-1]);
}
else{
printf("Invalid Operator\n");
return EXIT_FAILURE;
}
if ((u) == 1)
{
printf("stack_last= %lf\n",stack[u-1]);
result = stack[u-1];
for(int d =0;d<len; d++)
{
free(input[d]);
}
free(input);
free(stack);
return result;
}
u = u-1;
}
return EXIT_FAILURE;
}
int main (int argc, char ** argv) {
if (argc != 2) {
fprintf(stderr, "Incorrect number of arguments.\n");
fprintf(stderr, "Usage: ./pa11 <input file>\n");
return EXIT_FAILURE;
}
float result; //store the result of your calculation here.
result=(rpn(argv[1]));
fprintf(stdout,"Result = %f\n", result);
return EXIT_SUCCESS;
}
and these are the errors from valgrind
==7692== Invalid write of size 1
==7692== at 0x391C858C76: _IO_vfscanf (vfscanf.c:1110)
==7692== by 0x391C8645EA: __isoc99_fscanf (isoc99_fscanf.c:35)
==7692== by 0x401320: rpn (pa11.c:70)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e5b1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x391C83AC70: ____strtod_l_internal (strtod_l.c:732)
==7692== by 0x401411: rpn (pa11.c:79)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e5b1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x391C83A478: ____strtod_l_internal (strtod_l.c:787)
==7692== by 0x401411: rpn (pa11.c:79)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e5b1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid write of size 1
==7692== at 0x391C858257: _IO_vfscanf (vfscanf.c:1031)
==7692== by 0x391C8645EA: __isoc99_fscanf (isoc99_fscanf.c:35)
==7692== by 0x401320: rpn (pa11.c:70)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e601 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x391C839E30: str_to_mpn (strtod_l.c:327)
==7692== by 0x391C83B3D2: ____strtod_l_internal (strtod_l.c:1115)
==7692== by 0x401411: rpn (pa11.c:79)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e601 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x4A084E8: strcmp (mc_replace_strmem.c:729)
==7692== by 0x40133D: rpn (pa11.c:75)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e6a1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x4A084E8: strcmp (mc_replace_strmem.c:729)
==7692== by 0x401374: rpn (pa11.c:75)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e6f1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
numbers= 3
num_op= 2
index= 3
==7692== Invalid read of size 1
==7692== at 0x4A084E8: strcmp (mc_replace_strmem.c:729)
==7692== by 0x401619: rpn (pa11.c:99)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e6a1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x4A084E8: strcmp (mc_replace_strmem.c:729)
==7692== by 0x401650: rpn (pa11.c:99)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e6f1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x391C83AC70: ____strtod_l_internal (strtod_l.c:732)
==7692== by 0x40177B: rpn (pa11.c:112)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e5b1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x391C83A478: ____strtod_l_internal (strtod_l.c:787)
==7692== by 0x40177B: rpn (pa11.c:112)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e5b1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x391C839E30: str_to_mpn (strtod_l.c:327)
==7692== by 0x391C83B3D2: ____strtod_l_internal (strtod_l.c:1115)
==7692== by 0x40177B: rpn (pa11.c:112)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e601 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
==7692== Invalid read of size 1
==7692== at 0x4A084E8: strcmp (mc_replace_strmem.c:729)
==7692== by 0x4017E8: rpn (pa11.c:134)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e6a1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
Result + = 12.000000
==7692== Invalid read of size 1
==7692== at 0x4A084E8: strcmp (mc_replace_strmem.c:729)
==7692== by 0x40187C: rpn (pa11.c:141)
==7692== by 0x401CAD: main (pa11.c:199)
==7692== Address 0x4c3e6f1 is 0 bytes after a block of size 1 alloc'd
==7692== at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==7692== by 0x4012F4: rpn (pa11.c:68)
==7692== by 0x401CAD: main (pa11.c:199)
==7692==
Result - = -5.000000
stack_last= -5.000000
Result = -5.000000
==7692==
==7692== HEAP SUMMARY:
==7692== in use at exit: 0 bytes in 0 blocks
==7692== total heap usage: 10 allocs, 10 frees, 1,773 bytes allocated
==7692==
==7692== All heap blocks were freed -- no leaks are possible
==7692==
==7692== For counts of detected and suppressed errors, rerun with: -v
==7692== ERROR SUMMARY: 28 errors from 14 contexts (suppressed: 6 from 6)