Reputation: 1
I am new to C, and came across a problem that I don't know how to solve. Could you have a look at buffer[fileSize]
in unwhiten
()? The problem that I'm having is that if I run this code, I will get a segmentation fault, but if I replace fileSize
with any integer, the problem goes away. However, I defined fileSize
as int, and I print it out, which also gives me an integer, so I really don't understand what happened or why it happened. Thank you!
#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;
}
Upvotes: 0
Views: 85
Reputation: 141534
strcpy(ft,pattern);
is a problem. The strcpy
function expects a null-terminated string, howeover pattern
is not that. The strcpy
will read past the end of pattern
, causing undefined behaviour. You probably want to put a null terminator on (and increase the allocations of ft
and pattern
by one). It'd make sense to use sizeof pattern
in your malloc
rather than re-computing the size.
I'd also advise changing exp2(patternLength)
to 1ul << patternLength
, that avoids any possibility of rounding errors (exp2
is a floating point function).
Finally it'd be good to do some sanity checking on any values you use to size a VLA, e.g. char recoveredBits[readNum];
. If readNum
was negative, or less than patternLength
, or something else you didn't expect, then you just get silent undefined behaviour which is hard to track down the source of.
Upvotes: 1