Search code examples
cmatrixlinked-listboggle

Getting empty length


This function is where I insert the node along with its data to the linked list.

void insertNodeAndWord(struct ListNode ** pointerToHead, char word[16]) {
    struct ListNode * newNode = (struct ListNode *)malloc(sizeof(struct      ListNode));
    newNode->word = word;
    newNode->next = NULL;

    //printf("%s\n", newNode->word); // Prints out the correct words when i     try to print from here.

    if(*pointerToHead == NULL) {
        newNode->next = *pointerToHead;
    }
    *pointerToHead = newNode;
}

This function is where I get all the words from the boggle board (this function seems to work correctly, since when I print out the words here, it prints it out correctly.

struct ListNode * getAllWords(char currWord[16], int x, int y, const char     board[4][4], int check[4][4], struct ListNode * list) {
    if(x<0||y<0||x>=4||y>=4) { //base case
        return list;
    } else if (check[x][y] == 0) {
        char newWord[16];
        strcpy(newWord, currWord);
        if(isPrefix(newWord) == 0) {
            return list;
        }
        int length = strlen(newWord);
        newWord[length] = board[x][y];
        newWord[length+1] = '\0';

        if(isWord(newWord) != 0) {
            insertNodeAndWord(&list, newWord);
            //printf("%s\n", list->word); // Prints out the correct words when i try to print from here.
            printf("Length: %d\n", listLength(list)); // Prints out 1 every time.
        }
        int row, col;
        for(row =-1; row<=1; row++) {
            for(col=-1; col<=1; col++) {//
                check[x][y] = 1; //marks the board tile as visited
                getAllWords(newWord, x+row, y+col, board, check, list);
                check[x][y] = 0; //unmarks the board tile as visited
            }
        }
    }
    return list;
}


struct ListNode * findWords(const char board[4][4]) {
    int x, y;
    int check[4][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0,    0}};
    char word[16] = "";
    struct ListNode * list;
    list = NULL;
    for(x=0; x<4; x++) {
        for(y=0; y<4; y++) {
            getAllWords(word, x, y, board, check, list);
            // printf("%s\n", list->word); // I get a "has stopped working" error here when i try to print out the words.
        }
    }
    return list;
 }

Solution

  • Problems I see:

    Problem 1

    newNode->word = word;
    

    is not right. Every node in the linked list will store a pointer to same block of memory, which is passed from getAllWords. Worse, that block of memory corresponds to a function local variable in getAllWords that will no longer be valid once you return from getAllWords. You will end up with nodes pointing to dangling memory.

    You need something like

    newNode->word = strdup(word);
    

    Problem 2

    It's not clear whether insertNodeAndWord should add the new node at the end of the list or at the start of the list.

    If you want to add it at the start of the list, your function can be:

    void insertNodeAndWord(struct ListNode ** pointerToHead, char word[16]) {
       struct ListNode * newNode = malloc(sizeof(struct ListNode));
       newNode->word = strdup(word);
       newNode->next = *pointerToHead;
       *pointerToHead = newNode;
    }
    

    If you want to add the new node to the end of the list, the logic is a little more involved.

    Problem 3

    You are not using the return value of getAllWords where it gets called.

    Change the line (in getAllWords)

            getAllWords(newWord, x+row, y+col, board, check, list);
    

    to

            list = getAllWords(newWord, x+row, y+col, board, check, list);
    

    Change the line (in findWords)

         getAllWords(word, x, y, board, check, list);
    

    to

         list = getAllWords(word, x, y, board, check, list);
    

    Miscellaneous

    As a good programming practice, always check the value returned from malloc. That way, you avoid the unpleasant consequences of dereferencing a NULL pointer.

    struct ListNode * newNode = malloc(sizeof(struct ListNode));
    if ( newNode == NULL )
    {
       // Deal with error condition.
       // This is one way to deal with it - print an error message and exit.
       perror("Unable to get memory for a ListNode.\n");
       exit(EXIT_FAILURE);
    }