C中的神秘分割错误

时间:2014-04-26 11:09:44

标签: c segmentation-fault

我是C的新手,遇到了一个我不知道如何解决的问题。你能看一下buffer[fileSize]()中的unwhiten吗?我遇到的问题是,如果我运行此代码,我将得到分段错误,但如果我用任何整数替换fileSize,问题就会消失。但是,我将fileSize定义为int,并将其打印出来,这也给了我一个整数,所以我真的不明白发生了什么或为什么会发生。谢谢!

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define BUFFER_SIZE 1000000
#include <string.h>
#include "whiten.h"


int main (int agrc, char *agrv[])
{
  whiten ();
  unwhiten ();

  return 0 ;
}


void unwhiten ()
 {
     FILE *input =fopen("2.txt","rb") , *output =  fopen("3.txt","ab") ;
     int patternLength =2 ,entryNum=0,counter=0 ,readNum,numProcessed=0 ,index ,fileSize;
     fseek(input,0L,SEEK_END);
     fileSize=ftell(input);
     fseek(input,0L,SEEK_SET);
     char buffer[fileSize] ,pattern[patternLength] ,*ft ;
     struct Entry table[ (int)exp2(patternLength)]  ;
     readNum=fread(buffer,sizeof(buffer[0]),sizeof (buffer),input);
     char recoveredBits[readNum];
     for (counter;counter<patternLength;counter++)  // output the first t bits and record the first pattern
     {
         if (buffer[counter]=='1')
         {
             fputc('1',output);
             recoveredBits[counter]='1';
         }
         else
         {
             fputc('0',output);
             recoveredBits[counter]='0';
         }

            pattern[counter]=buffer[counter];
     }
     numProcessed=patternLength;
       while (numProcessed<readNum)
     {
          index=searchTable(table,entryNum,pattern) ;

         if ( index==-1) // the table doesnt contain the entry
         {
              ft=malloc (sizeof (char)*(int)exp2(patternLength));
              strcpy(ft,pattern);
              table[entryNum].key=ft;
              table[entryNum].numOf0=0;
              table[entryNum].numOf1=0;
              index = entryNum++;
          }
               if (table[index].numOf0>=table[index].numOf1)//  they are equally likely
              {
                  if (buffer[numProcessed]=='0')  // prediction is made ,and it is right
                  {
                      fputc('0',output);
                      table[index].numOf0++;
                      recoveredBits[numProcessed]='0';
                  }
                  else
                  {
                       fputc('1',output); // prediction is wrong
                       table[index].numOf1++;
                       recoveredBits[numProcessed]='1';
                  }
              }
              else
              {
                  if (buffer[numProcessed]=='1')  // prediction is made ,and it is right
                  {
                       fputc('0',output);
                      table[index].numOf0++;
                      recoveredBits[numProcessed]='0';
                  }
                  else
                  {
                      fputc('1',output); // prediction is wrong
                      table[index].numOf1++;
                      recoveredBits[numProcessed]='1';
                  }
              }
           for (counter=1;counter<patternLength;counter++)  // shuffle the array
         {
             pattern[counter-1]=pattern[counter];
         }
         pattern[patternLength-1]=recoveredBits[numProcessed++];
       }
     fclose(input);
     fclose(output);

     for (counter=0;counter<entryNum;counter++)
     {
         free(table[counter].key);
     }

 }




 void whiten ()
 {
     FILE *input =fopen("1.txt","rb") , *output =  fopen("2.txt","ab") ;
     int patternLength =2 ,entryNum=0,counter=0 ,readNum,numProcessed=0 ,index;
     char buffer[BUFFER_SIZE] ,pattern[patternLength] ,*ft ;
     struct Entry table[ (int)exp2(patternLength)]  ;
     readNum=fread(buffer,sizeof(buffer[0]),sizeof (buffer),input);
     for (counter;counter<patternLength;counter++)  // output the first t bits and record the first pattern
     {
         if (buffer[counter]=='1')
             fputc('1',output);
         else
            fputc('0',output);
            pattern[counter]=buffer[counter];
     }
     numProcessed=patternLength;
       while (numProcessed<readNum)
     {
          index=searchTable(table,entryNum,pattern) ;

         if ( index==-1) // the table doesnt contain the entry
         {
              ft=malloc (sizeof (char)*(int)exp2(patternLength));
              strcpy(ft,pattern);
              table[entryNum].key=ft;
              table[entryNum].numOf0=0;
              table[entryNum].numOf1=0;
              index = entryNum++;
          }
               if (table[index].numOf0>=table[index].numOf1)//  they are equally likely
              {
                  if (buffer[numProcessed]=='0')  // prediction is made ,and it is right
                  {
                      fputc('0',output);
                      table[index].numOf0++;
                  }
                  else
                  {
                       fputc('1',output); // prediction is wrong
                       table[index].numOf1++;
                  }
              }
              else
              {
                  if (buffer[numProcessed]=='1')  // prediction is made ,and it is right
                  {
                      fputc('0',output);
                      table[index].numOf1++;
                  }
                  else
                  {
                      fputc('1',output); // prediction is wrong
                      table[index].numOf0++;
                  }
              }
           for (counter=1;counter<patternLength;counter++)  // shuffle the array
         {
             pattern[counter-1]=pattern[counter];
         }
         pattern[patternLength-1]=buffer[numProcessed++];
       }
     fclose(input);
     fclose(output);

     for (counter=0;counter<entryNum;counter++)
     {
         free(table[counter].key);
     }

 }

int searchTable ( struct Entry table[],int entryNum,char pattern[])
{
    int i=0;
    for (i;i<entryNum;i++)
    {
        if (strcmp(table[i].key,pattern)==0)
            return i;
    }

    return -1;
}

1 个答案:

答案 0 :(得分:1)

strcpy(ft,pattern);是个问题。 strcpy函数需要一个以null结尾的字符串,而不是patternstrcpy将读取pattern的结尾,导致未定义的行为。您可能希望打开一个空终止符(并将ftpattern的分配增加一个)。在sizeof pattern中使用malloc而不是重新计算大小是有意义的。

我还建议将exp2(patternLength)更改为1ul << patternLength,以避免出现舍入错误的可能性(exp2是浮点函数)。

最后,对用于调整VLA大小的任何值进行一些完整性检查是很好的,例如: char recoveredBits[readNum];。如果readNum为负数,或者低于patternLength,或者您没有预料到的其他内容,那么您只会获得无法定义的未定义行为,这很难追查其来源。