***“./a.out&#39 ;:双重免费或损坏(!prev)错误:0x0000000000bb0470 ***

时间:2018-03-18 12:17:50

标签: c free corruption

运行c程序时出现以下错误:

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

我相信这是因为在程序中调用了fclose(),它是一个用于c语言编译器的词法分析器,它使用文件指针。 这是代码:

    #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);
}

`./a.out'中的错误:双重免费或损坏(!prev):0x0000000000bb0470

这个程序中有多个文件操作,它包括源程序(它是简单的c程序,没有预处理器),终端故事作为输入,这个文本文件需要在运行上面的代码之前创建

TT.txt =&gt;

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 =&gt;

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

谢谢!

3 个答案:

答案 0 :(得分:3)

除了其他问题,valgrind报告

==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)

这两行是

127                     fclose(fp_LT);
...
135                             fclose(fp_LT);

答案 1 :(得分:2)

正如@ensc所提到的,在代码的第135行中,在if(flag_LT==0)案例中,您致电fclose(fp_LT),但您已在第127行关闭它。

工具cppcheck也发现了这个错误。

您可以使用rewind()返回文件的开头,而不是重复打开和关闭同一文件。此外,您的计划未检查任何fopen()fscanf()fclose()来电的结果。这意味着如果您有损坏的数据,或者读取和写入文件有任何错误,您的程序将忽略这些错误,可能会产生不良后果。

答案 2 :(得分:1)

这部分看起来很可疑:

                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

如果flag_LT为零,则您似乎两次致电fclose。这是未定义的行为。