我是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;
}
答案 0 :(得分:1)
strcpy(ft,pattern);
是个问题。 strcpy
函数需要一个以null结尾的字符串,而不是pattern
。 strcpy
将读取pattern
的结尾,导致未定义的行为。您可能希望打开一个空终止符(并将ft
和pattern
的分配增加一个)。在sizeof pattern
中使用malloc
而不是重新计算大小是有意义的。
我还建议将exp2(patternLength)
更改为1ul << patternLength
,以避免出现舍入错误的可能性(exp2
是浮点函数)。
最后,对用于调整VLA大小的任何值进行一些完整性检查是很好的,例如: char recoveredBits[readNum];
。如果readNum
为负数,或者低于patternLength
,或者您没有预料到的其他内容,那么您只会获得无法定义的未定义行为,这很难追查其来源。