问题
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",<1.SR,<1.name,<1.precision,<1.base,<1.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!
回答1:
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);
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/49347778/error-in-a-out-double-free-or-corruption-prev-0x0000000000bb0470