Reputation: 7
This is an incomplete code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define W 1031
#define B 256
struct FileCoordinates{
int x; /*line number*/
int y; /*word number*/
struct FileCoordinates *next;
};
struct FileStruct{
char *filename;
struct FileCoordinates *coordinates;
struct FileStruct *next;
};
struct WordStruct{
char *word;
struct WordStruct *left;
struct WordStruct *right;
struct FileStruct *files;
};
typedef struct FileCoordinates *CoorPtr;
typedef struct FileStruct *FilePtr;
typedef struct WordStruct *WordPtr;
WordPtr HashTable[W];
long int power(int a, long b){
long int pow, i;
pow = 1;
for (i = 0; i < b; i++){
pow = pow*a;
}
return pow;
}
int hashvalue (char *word){
long int i, value=0, n;
n = strlen(word);
for (i=0; i<n; i++){
value = value + power(B,n-i-1) * word[i];
}
return(value%W);
}
void putPosition(int x, int y, FilePtr *currfile){
CoorPtr currcors = (*currfile)->coordinates;
while (currcors!=NULL){
currcors = currcors->next;
}
currcors = (CoorPtr)malloc(sizeof(struct FileCoordinates));
currcors->x=x;
currcors->y=y;
}
void putFile(char *filename, WordPtr *currWord, int x, int y){
FilePtr currfile = (*currWord)->files;
while(currfile != NULL && strcmp(currfile->filename,filename)!=0){
currfile=currfile->next;
}
if (strcmp(currfile->filename,filename)==0){
putPosition(x, y, &currfile);
}
else{
currfile = (FilePtr)malloc(sizeof(struct FileStruct));
currfile->filename = filename;
putPosition(x, y, &currfile);
}
}
void insert(char *word, WordPtr *leaf, char *filename, int x, int y)
{
if( *leaf == NULL )
{
*leaf = (WordPtr) malloc( sizeof( struct WordStruct ) );
(*leaf)->word = word;
putFile(filename, &(*leaf), x, y);
/* initialize the children to null */
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(word < (*leaf)->word)
{
insert( word, &(*leaf)->left, filename, x, y);
}
else if(word > (*leaf)->word)
{
insert( word, &(*leaf)->right, filename, x, y);
}
else if(word == (*leaf)->word){
putFile(filename, &(*leaf), x, y);
}
}
int main(int argc, char *argv[]){
int i, words, lines, value;
char *filename, *word, c;
FILE *fp;
word = (char *)malloc(21*sizeof(char));
if (argc<2){
perror("no files were inserted");
}
for (i=1; i<argc; i++){
words=1;
lines=1;
fp = fopen(argv[i], "r");
if (fp==NULL){
printf("Could not open file named %s! \n", argv[i]);
return 2;
}
filename = malloc( strlen( argv[i] ) + 1 );
strcpy( filename, argv[i] );
fscanf(fp, "%s", word);
value=hashvalue(word);
c=getc(fp);
insert(word, &HashTable[value], filename, lines, words);
if (c==' '){
words = words+1;
}
else if(c=='\n'){
lines=lines+1;
words=1;
}
}
system("PAUSE");
return 0;
}
And debugger gives me segmentation fault at this part:
while(currfile != NULL && strcmp(currfile->filename,filename)!=0){
currfile=currfile->next;
}
The reason of the code is to get text files as arguments, sort the words into binary trees placed in the hashtable and then by searching the keyword it shows you the coordinates it appears.
Anyway, i know this is a very novice code but im trying to understand.
Upvotes: 0
Views: 81
Reputation: 44181
Where do you initialize files
? (Hint: you don't). This means it is an undefined value (not necessarily NULL). You need to initialize files
before calling putFile
.
As noted in the comment, once you fix that one, you need to do the same for next
in both FileCoordinates
and FileStruct
and for coordinates
in FileStruct
.
Also as noted in the comments, you reuse the word
buffer, meaning that all the nodes in the tree will have the same string. You should allocate a new buffer for the string when it is stored in the tree. Perhaps use strdup
.
(*leaf)->word = strdup(word);
Once that is fixed, you also need to work on your string comparison. if(word == (*leaf)->word)
compares the pointers, not their contents. You need to use strcmp
if you want to compare the actual string data.
else if(strcmp(word, (*leaf)->word) == 0){
Upvotes: 0
Reputation: 41017
You forget to set currfile->next
to NULL
when you create the object:
currfile = (FilePtr)malloc(sizeof(struct FileStruct));
currfile->filename = filename;
Reserve space with calloc
instead of malloc
, or add:
currfile->next = NULL;
Upvotes: 2