0

for Pset5 speller my code for load along with the generation of hash codes leads to a segmentation fault. I realized it is because fscanf returns 0 after the last word of the dictionary, leading to -97 being returned but I cant figure out why it returns that instead of EOF,

unsigned int hash(const char *word)
{   int first = 0;
    // TODO: Improve this hash function
    // return 0-25 according to first letter of the word
        int test = word[0]; //why does 2nd word[0] = 0
        first = (int)word[0] - 97;


    return first;
}
bool load(const char *dictionary)

{

FILE *dict = fopen(dictionary, "r");
char *tmpword;
//allocate space for the words


int code;

do
{
    tmpword = malloc(LENGTH +8);
     if (tmpword == NULL)
    {
        return 1;
    }

     node *n = malloc(sizeof(node));

    fscanf(dict, "%s", tmpword); //after 2 words in dictionaries small, cant end fscanf returns 0 value

    strcpy(n->word,tmpword);
    code=hash(tmpword);


    n->next = table[code];
    table[code]=n;

}
while (*tmpword!= EOF); //has to be done earl





free(tmpword);
fclose(dict);



return false;

}

1 Answer 1

0

The problem is that this code is executing the fscanf and processing whatever is read before it checks for EOF.

There are several subtleties that are interacting here, leading to your result. First, the EOF flag is only set after an attempt to read past the end of the file. If the code reads right up to the end, but doesn't go any further, as it does here, the EOF flag is not set, so the loop executes one more time.

On that last pass, the fscanf attempts to read from the file. Since there's nothing to read, nothing is written into tmpword, so tmpword remains unchanged from whatever it contained before. Ordinarily, people use a string var (ie, a char array), that gets reused over and over. In that case, the string var would have the last word read, so it would just reprocess the last word a second time. In this case, tmpword gets new memory allocated on every loop with a malloc call. That means that the memory allocated will contain whatever unpredictable data that was left in memory, ie, garbage data, after that last fscanf call. BTW, this will also lead to a massive memory leak because tmpword has memory allocated for every word, but only frees the last word after the loop ends.

The fscanf return value should be checked immediately after execution for EOF, or better still, the fscanf should be incorporated into the loop statement, such as a while statement, so that the code doesn't attempt to process anything when EOF is set.

As for the hash returning a negative value, it's trying to hash an unpredictable value, probably 0x00, rather than an actual word. If it returns a negative hash, then a seg fault is inevitable.

Programming note: The hash function should have code added to guarantee that the value to be returned is within the acceptable range of the table array.

This should get you going again. Happy coding! ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

1
  • thanks, managed to get load working with your help!
    – duckpro
    Commented Jan 14, 2023 at 9:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .