-3

I get the following error when running a c program:

*** Error in `./a.out': double free or corruption (!prev): 0x0000000000bb0470 ***

I believe this is due to fclose() being called in the program, It is a Lexical Analyzer for compilers in c language and it uses file pointers . Here is code:

    #include<stdio.h>
#include<string.h>

typedef struct Terminal_table
{
    int index;  
    char symbol[10],indicator;      
}Terminal_table;

typedef struct  Identifier_table
{
    int index;  
    char name[10];      
}Identifier_table;

typedef struct Literal_table
{   
    int SR,name,precision;  
    char base[10],scale[10];        
}Literal_table;

typedef struct Uniform_symbol_table
{   
    int SR,index;   
    char name[10],symbol_class[10];
}Uniform_symbol_table;

int main()
{
    FILE *fp_PGM,*fp_TT,*fp_LT,*fp_UST,*fp_IT,*fp_IT1,*fp_LT1;

    Terminal_table TT;  
    Identifier_table IT,IT1;
    Literal_table LT,LT1;   
    Uniform_symbol_table UST;

    int i=0,flag,flag_IT,flag_LT,a;     
    char ch,buffer[10];

    fp_PGM=fopen("PGM_LEX.txt","r");
    fp_UST=fopen("UST.TXT","w");
    fp_IT=fopen("IT.TXT","w");
    fp_LT=fopen("LT.TXT","w");

    UST.SR=1;   
    IT.index=1; 
    LT.SR=1;

    for(i=0;i<10;i++)
        buffer[i]='\0';
    i=0;

    while(!feof(fp_PGM))
    {
        ch=fgetc(fp_PGM);
        if(isalpha(ch) || isdigit(ch))
            buffer[i++]=ch;

        else if(ch!='"')
        {
            flag=0;
            fp_TT=fopen("TT.txt","r");
            while(!feof(fp_TT))
            {
                fscanf(fp_TT,"%d %s %c\n",&TT.index,&TT.symbol,&TT.indicator);
                if(strcmp(TT.symbol,buffer)==0)
                {
                    flag=1;
                    strcpy(UST.name,buffer);    
                    UST.index=TT.index;
                    if(TT.indicator=='Y')
                        strcpy(UST.symbol_class,"TRM");
                    else    
                        strcpy(UST.symbol_class,"KEY");
                    fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,UST.index);
                    break;
                }
            }
            fclose(fp_TT);
            if(flag==0)
            {
                if(isalpha(buffer[0]))
                {
                    flag_IT=0;  
                    fclose(fp_IT);
                    fp_IT1=fopen("IT.TXT","r");
                    while(!feof(fp_IT1))
                    {
                        fscanf(fp_IT1,"%d %s\n",&IT1.index,IT1.name);
                        if(strcmp(IT1.name,buffer)==0)
                        {
                            flag_IT=1;  
                            break;
                        }
                    }
                    fclose(fp_IT1);     
                    strcpy(UST.name,buffer);
                    UST.index=TT.index; 
                    strcpy(UST.symbol_class,"IDN");

                    if(flag_IT==1)
                        fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,IT1.index);
                    if(flag_IT==0)
                    {
                        fp_IT=fopen("IT.TXT","a");
                        strcpy(IT.name,buffer);
                        fprintf(fp_IT,"%d %s\n",IT.index++,IT.name);
                        fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,IT.index-1);
                        fclose(fp_IT);
                    }
                }
                else if(isdigit(buffer[0]))
                {
                    flag_LT=0;
                    fclose(fp_LT);
                    fp_LT=fopen("LT.TXT","r");
                    while(!feof(fp_LT))
                    {
                        fscanf(fp_LT,"%d %d %s %s %s\n",&LT1.SR,&LT1.name,&LT1.precision,&LT1.base,&LT1.scale);
                        a=atoi(buffer);
                        if(LT1.name==a)
                        {
                            flag_LT=1;  
                            break;
                        }
                    }
                    fclose(fp_LT);
                    strcpy(UST.name,buffer);
                    UST.index=TT.index;
                    strcpy(UST.symbol_class,"LIT");
                    if(flag_LT==1)
                        fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,LT1.SR);
                    if(flag_LT==0)
                    {
                        fclose(fp_LT);
                        fp_LT=fopen("LT.TXT","a");
                        LT.name=atoi(buffer);
                        LT.precision=2; 
                        strcpy(LT.base,"DECIMAL");
                        strcpy(LT.scale,"FIXED");
                        strcpy(UST.name,buffer);
                        fprintf(fp_LT,"%d %d %d %s %s\n",LT.SR++,LT.name,LT.precision,LT.base,LT.scale);
                        fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,LT.SR-1);
                        fclose(fp_LT);
                    }
                }
            }
            for(i=0;i<10;i++)
                buffer[i]='\0';
            buffer[0]=ch;
            fp_TT=fopen("TT.txt","r");
            while(!feof(fp_TT))
            {
                fscanf(fp_TT,"%d %s %c\n",&TT.index,&TT.symbol,&TT.indicator);
                if(strcmp(TT.symbol,buffer)==0)
                {
                    strcpy(UST.name,buffer);
                    UST.index=TT.index;
                    strcpy(UST.symbol_class,"TRM");
                    fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,UST.index);
                    break;
                }
            }
            for(i=0;i<10;i++)       
                buffer[i]='\0';
            fclose(fp_TT);
            i=0;
        }
        else if(ch=='"')
        {
            buffer[0]=ch;
            fp_TT=fopen("TT.txt","r");
            while(!feof(fp_TT))
            {
                fscanf(fp_TT,"%d %s %c\n",&TT.index,&TT.symbol,&TT.indicator);
                if(strcmp(TT.symbol,buffer)==0)
                {
                    strcpy(UST.name,buffer);
                    UST.index=TT.index;
                    if(TT.indicator=='Y')
                        strcpy(UST.symbol_class,"TRM");
                    else
                        strcpy(UST.symbol_class,"KEY");
                    fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,UST.index);
                    break;
                }
            }
            fclose(fp_TT);      
            ch=fgetc(fp_PGM);
            while(ch!='"')
            {
                ch=fgetc(fp_PGM);
            }
            strcpy(UST.name,buffer);    
            UST.index=TT.index;
            if(TT.indicator=='Y')
                strcpy(UST.symbol_class,"TRM");
            else    
                strcpy(UST.symbol_class,"KEY");
            fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,UST.index);
            ch=fgetc(fp_PGM);
        }
    }
    fclose(fp_PGM); 
    fclose(fp_UST);     
    fclose(fp_IT);      
    fclose(fp_LT);
}

Error in `./a.out': double free or corruption (!prev): 0x0000000000bb0470

there are multiple files operations in this program it includes source program (it is simple c program without preprocessors), Terminal tale as input and this text files need to be already created before running above code

TT.txt =>

1   void    N
2   main    N
3   int N
4   float   N
5   printf  N
6   scanf   N
7   ,   Y
8   ;   Y
9   =   Y
10  "   Y
11  {   Y
12  }   Y
13  *   Y
14  /   Y
15      +       Y
16  -   Y
17  (   Y
18  )   Y
19  <   Y
20  >   Y
21  getch   N

PGM_LEX.txt =>

void main()
{
    int i=10,j;
    printf("%d",i);
    i=(j/10);
    getch();        
}

thanks!

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
Shubham Kadam
  • 21
  • 1
  • 2
  • This error means that you have corrupted memory somehow -- typically accidental pointer references that overwrite memory it wasn't supposed to. – Steve Summit Mar 18 '18 at 12:47
  • 1
    run it through `valgrind`; it will tell you where memory has been freed previously. – ensc Mar 18 '18 at 12:50
  • There are many problems in your code, I don't have time to find them all. But here's one example: I noticed several instances of `strcpy(UST.name,buffer);`. But `buffer` had not been constructed to contain a proper null-terminated string: in once case I noticed it had just one character in it. Without null termination, `strcpy` is going to read arbitrarily namy characters and copy them to `UST.name`, which has room for only 10 characters. Boom! – Steve Summit Mar 18 '18 at 12:56

3 Answers3

2

Beside other problems, valgrind reports

==27338== Invalid read of size 4
==27338==    at 0x4EA57D4: fclose@@GLIBC_2.2.5 (in /usr/lib64/libc-2.26.so)
==27338==    by 0x400B32: main (gggg4.c:135)
==27338==  Address 0x5211310 is 0 bytes inside a block of size 552 free'd
==27338==    at 0x4C2DD18: free (vg_replace_malloc.c:530)
==27338==    by 0x4EA587D: fclose@@GLIBC_2.2.5 (in /usr/lib64/libc-2.26.so)
==27338==    by 0x400AFB: main (gggg4.c:127)
==27338==  Block was alloc'd at
==27338==    at 0x4C2CB6B: malloc (vg_replace_malloc.c:299)
==27338==    by 0x4EA622C: __fopen_internal (in /usr/lib64/libc-2.26.so)
==27338==    by 0x400E00: main (gggg4.c:116)

These two lines are

127                     fclose(fp_LT);
...
135                             fclose(fp_LT);
ensc
  • 6,704
  • 14
  • 22
1

As @ensc mentioned, in line 135 of your code, in the if(flag_LT==0) case, you call fclose(fp_LT), but you already closed it in line 127.

The tool cppcheck also finds this bug.

Instead of repeatedly opening and closing the same file, you can use rewind() to go back to the start of a file. Also, your program is not checking the result of any of the fopen(), fscanf() and fclose() calls. That means that if you have corrupted data, or there are any errors reading and writing the files, your program will ignore these errors, with possibly bad consequences.

G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
0

This section looks suspicious:

                fclose(fp_LT);              // fp_LT is closed
                strcpy(UST.name,buffer);
                UST.index=TT.index;
                strcpy(UST.symbol_class,"LIT");
                if(flag_LT==1)
                    fprintf(fp_UST,"%d %s %s %d \n",UST.SR++,UST.name,UST.symbol_class,LT1.SR);
                if(flag_LT==0)
                {
                    fclose(fp_LT);            // fp_LT is closed again

In case flag_LT is zero, it seems you call fclose twice. That is undefined behavior.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63