1

I hope you are well. I am currently on pset 5 where you have to write a spell checker. I am stuck on the load function.

I am able to get stuff into my linked list. when I make and run it, I get a bunch of wierd text as follows.

speller: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *)
&((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd))))
&& old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)
((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *
(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 
0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.

loaded 36 words into memory Aborted

Is there something that I am missing here? If so please give me a few pointers in the right direction.

I feel like I am close with this function. I know that there are four functions but I am taking this one function at a time (meaning that I cannot advance onto the check until I have finished up load). I have attached the code from my function below

Update: I have fixed it thanks to some folks in the CS50 subreddit. However, after running it through debug50 the hashtable is not being filled in correctly. I have updated the code below to reflect this.

Kind regards, Adi (a CS50 student in London, UK)

// Open the dictionary file
FILE* d_ptr = fopen(dictionary, "r");

// Check if the file exists or not (or if there are any other errors)
if (d_ptr == NULL)
{
    printf("File does not exist.\n");
    fclose(d_ptr);
    return false;
}

int wordCounter = 0;
char word[LENGTH + 1];
int index= 0;
int hashIndex = 0;
char c = 'a';

node* hashTable[26];
node* first = NULL;
node* newPtr;
node* ptr = first;

// Open the dictionary file
FILE* d_ptr = fopen(dictionary, "r");

// Check if the file exists or not (or if there are any other errors)
if (d_ptr == NULL)
{
    printf("File does not exist.\n");
    return false;
}

int wordCounter = 0;
char word[LENGTH + 1];
int index= 0;
int hashIndex = 0;
char c = 'a';

node* hashTable[26];
node* first = NULL;
node* newPtr;
node* ptr = first;

do 
{
    newPtr= malloc(sizeof(node));
    if (newPtr == NULL)
    {
        return false;
    }

    // get the word ready to be hashed
    while ( isalpha(c = fgetc(d_ptr)))
    {
        word[index] = c;
        index++;
    }

    if (c == 0x0A || c == ' ')
    {
        word[index] = '\0';
        index = 0;

        hashIndex = hash(word[0]);
    }

    strncpy(newPtr->wordArray,word,sizeof(word));
    newPtr->next = NULL;

    if (first == NULL)
    {
        first = newPtr;
    }
    else if (newPtr->wordArray < first->wordArray)
    {
        newPtr->next = first;
        first = newPtr;
    }

    wordCounter++;
    ptr = newPtr->next;
    hashTable[hashIndex] = first;
}
while(!feof(d_ptr));

if (wordCounter >= 1)
{
    fclose(d_ptr);
    return true;
}
else
{
    // close the file 
    fclose(d_ptr);
    return false; 
}  

1 Answer 1

0

Assuming the hash table is going to look like this:

hashTable

[0] = a... -> a... -> a...

[1] = b... -> b... -> b...

.

.

.

[25] = z... -> z... -> z...

It is an array of linked lists. In one linked list every word starts with the same letter.

You are missing a connection between the first word of every linked list and the rest of the words.

I ran gdb on your load function. Although you seem to consistently be putting the first word in the correct linked list, the rest are lost and overwritten.

After you find out the hashIndex you should set your first node of that list:

first = hashTable[hashIndex];

You already check if the first node pointer is null correctly. But after that, you have a condition that I don't understand:

(newPtr->wordArray < first->wordArray)

It evaluated to false when I ran it. And because there was nothing to do in case it evaluated false (like another else if), it did nothing to newPtr and newPtr got overwritten later on without being saved anywhere.

Instead of this condition I would just follow your

if( first == NULL)

{

first = newPtr;

}

with something like:

else {

// Traverse until the end of the linked list and attach newPtr to the last node.
// You know that a node is the last node if its next pointer variable is NULL
// Something like this:
ptr = first;

do
{
    // Found last node
    if(ptr->next == NULL)
    {
        // Save ptr at the end of the list
        ptr->next = newPtr;
        // Break out of the do while loop
        break;
    }
    // else check next node
    else
    {
        ptr = ptr->next;
    }
} while(ptr->next != NULL);

}

1
  • Thanks for everyone's help with this one. After bouncing my issue with the folks on the CS50 subreddit my code is now working. I changed the condition of my while loop to use something else instead of feof. I used fscanf instead of fgetc (per Zamyla's walkthrough). I also declared my hashtable globally. I am now advancing onto unload (as I have already finished check and size). Commented Oct 21, 2016 at 14:19

You must log in to answer this question.

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