derpoverflow
derpoverflow

Reputation: 7

Why does this part gives segmentation fault?

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

Answers (2)

Dark Falcon
Dark Falcon

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

David Ranieri
David Ranieri

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

Related Questions