简体   繁体   中英

Segmentation fault while inserting into a hash table

I want to be able to use my getNextWord function to return a pointer to the next word in the file. I think I'm getting the seg fault while inserting but I just can't figure it out. Any help on this would be excellent. Also, I should probably find a better way of getting my hash_table_size than increasing a count for the total number of words in the file then rewinding. How can I make the size grow automatically?

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int hash_table_size;

char* getNextWord(FILE* fd) {
    char c;
    char buffer[256];
    int putChar = 0;
    while((c = fgetc(fd)) != EOF) {
        if(isalnum(c)) break;
    }
    if(c == EOF) return NULL;

    buffer[putChar++] = c;

    while((c = fgetc(fd)) != EOF) {
        if(isspace(c) || putChar >= 256 -1) break;

        if(isalnum(c))
            buffer[putChar++] = c;
    }

    buffer[putChar] = '\0';
    return strdup(buffer);
}

struct node {
    struct node *next;
    int count;
    char* key;
};

struct list {
    struct node *head;
    int count;
};

struct list *hashTable = NULL;

/*
 * djb2 hash function
*/
unsigned int hash(unsigned char *str) {
    unsigned int hash = 5381;
    int c;

    while(c == *str++)
        hash = ((hash << 5) + hash) + c;

    return (hash % hash_table_size);
}

struct node* createNode(char *key) {

    struct node *new_node;
    new_node = (struct node *)malloc(sizeof(struct node));
    strcpy(new_node->key, key);
    new_node->next = NULL;
    return new_node;
}

void hashInsert(char *str) {
    int hash_dex = hash(str);
    struct node *new_node = createNode(str);

    if(!hashTable[hash_dex].head) {
        hashTable[hash_dex].head = new_node;
        hashTable[hash_dex].count = 1;
        return;
    }

    new_node->next = (hashTable[hash_dex].head);

    hashTable[hash_dex].head = new_node;
    hashTable[hash_dex].count++;
    return;
}

void display() {
    struct node *current;
    int i;
    while(i < hash_table_size) {
        if(hashTable[i].count == 0)
            continue;
        current = hashTable[i].head;
        if(!current)
            continue;
        while(current != NULL) {
            char tmp[256];
            strcpy(tmp, current->key);
            printf("%s", tmp);
            current = current->next;
        }
    }
    return;
}

int main(int argc, char *argv[]) {

    if (argc != 2) {
        printf("Usage: ./hashFile textfile\n");
    }
    else {
        FILE *file = fopen(argv[1], "r");

        if(file == 0) {
            printf("Could not open file\n");
        }
        else {

            char *new_word;
            while((new_word = getNextWord(file)) != NULL) {
                hash_table_size++;
            }
            rewind(file);
            hashTable = (struct list *)calloc(hash_table_size, sizeof(struct list));
            while((new_word = getNextWord(file)) != NULL) {
                hashInsert(new_word);
            }
            display();
            fclose(file);
            }
        }
        return 0;
}
    int c;

    while(c == *str++)
        hash = ((hash << 5) + hash) + c;

c is not initialized here. As is i in display function. Please enable all the compiler warnings and fix them.

Also:

char c;

char buffer[256];
int putChar = 0;
while((c = fgetc(fd)) != EOF) {
    if(isalnum(c)) break;
}

c has to be of type int not char .

change

while(c == *str++)

to

while(c = *str++)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM