0

I keep getting segfault for my load function.

    bool load(const char *dictionary)
{
    //create a trie data type
   typedef struct node
   {
        bool is_word;
        struct node *children[27]; //this is a pointer too!  
   }node;

   //create a pointer to the root of the trie and never move this (use traversal *)
   node *root = malloc(sizeof(node));
   for(int i=0; i<27; i++)
   {
       //NULL point all indexes of root -> children
       root -> children[i] = NULL;
   }


   FILE *dptr = fopen(dictionary, "r");
   if(dptr == NULL)
   {
       printf("Could not open dictionary\n");
       return false;
   }



   char *c = NULL;


   //scan the file char by char until end and store it in c
   while(fscanf(dptr,"%s",c) != EOF)
   {
       //in the beginning of every word, make a traversal pointer copy of root so we can always refer back to root
       node *trav = root;

       //repeat for every word
       while ((*c) != '\0')
       {
        //convert char into array index
       int alpha = (tolower(*c) - 97);

       //if array element is pointing to NULL, i.e. it hasn't been open yet,
        if(trav -> children[alpha] == NULL)
            {
            //then create a new node and point it with the previous pointer. 
            node *next_node = malloc(sizeof(node));
            trav -> children[alpha] = next_node; 

            //quit if malloc returns null
            if(next_node == NULL)
                {
                    printf("Could not open dictionary");
                    return false;
                }

            }

        else if (trav -> children[alpha] != NULL)
            {
            //if an already existing path, just go to it
            trav = trav -> children[alpha];
            }   
       }
        //a word is loaded. 
        trav -> is_word = true;
   }
   //success
   free(root);
   return true;
}

I checked whether I properly pointed new pointers to NULL during initialization. I have three types of nodes: root, traversal (for moving), and next_node. (i.) Am I allowed to null point the nodes before mallocing them? (ii.) Also, how do I free 'next_node' if that node is initialized and malloced inside an if statement? node *next_node = malloc(sizeof(node)); (iii.) If I want to set the nodes as global variables, which ones should be global? (iv.) Lastly, where do I set global variables: inside the main of speller.c, outside its main, or somewhere else? That's alot of questions, so you don't have to answer all of them, but it would be nice if you could answer the answered ones! Please point out any other peculiarities in my code. There should be plenty. I will accept most answers.

1 Answer 1

0

root should be a global variable, so you can use it in various functions.

fscanf, when called with a NULL pointer, doesn't store anything. Your call to *c dereferences said NULL pointer, which causes a segfault as you are not allowed to read that page.

You can use char c[LENGTH+1]; instead of char *c;. +1 for the null terminator.

You need separate treatment for ' to have it mapped to 26.

Your initialisation of the root node is incomplete (you forgot is_word), you don't initialise the other nodes at all.

You need to advance in the tree regardless of whether you just added that node or used an existing one. The trav = trav -> children[alpha]; should not be in an else if path (especially with the if not making sense at all).

In load, do not free any node. They are essential parts of your trie.

2
  • Which line of the if statement is incorrect?
    – JadeHippo
    Commented Sep 6, 2017 at 8:09
  • if(trav -> children[alpha] == NULL) {} else if(trav -> children[alpha] != NULL) {} is same as if(trav -> children[alpha] == NULL) {} else {}, but in your case, there is no reason to use an else at all.
    – Blauelf
    Commented Sep 6, 2017 at 11:23

You must log in to answer this question.

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