Thread: LinkedList inside function woes

  1. #1
    Registered User
    Join Date
    Dec 2018
    Posts
    2

    Lightbulb LinkedList inside function woes

    Hi, I'm new to this board but I've found many helpful answers here in the past. I hope I will be able to give some answers of my own in the future too.

    When working on an assignment for my course regarding LinkedList structures I went a bit overboard trying to implement a "general" LinkedList. I've got most of it working but there is a bug that I just cannot figure out.

    The program is supposed to read from input, detect words (defined as alphanumeric sequences), and put them into a LinkedList structure while counting frequencies of each unique word.

    These are what I think are the relevant functions from my main file. There's more code that can be given if needed:

    Code:
    char * readWord() {
    
        // Reads an input stream, finds word as defined above, allocates memory, assigns,  and returns pointer to it.
    
        char * word;
        char inputArr[MAX_WORD_SIZE]; // dont expect words longer than 100 characters
        int length = 0;
        int chara;
    
        chara = getchar();
    
        while ((chara != EOF) && (length <= MAX_WORD_SIZE)) { //read until EOF at most
    
            if (isalnum(chara) != 0) {
                inputArr[length] = chara;
                length++;
            }
            else if ((isalnum(chara) == 0) && (length > 0)) {
    
                // Allocate word and return pointer
                word = malloc((length + 1) * sizeof(char)); // MALLOCED WORD - remember to free
    
                for (int i = 0; i < length; i++) { word[i] = inputArr[i]; }
    
                word[length] = '\0';
    
                return word; // user's responsibility to free word which is dynamically allocated on heap
            }
    
            chara = getchar();
    
        }
    
        print_list(head, print_data);
        printf("\nWaiting for input");
        scanf("Wait for input");
    
        return NULL; //can only get here if while loop fails, i.e. EOF
    
    }
    
    void count(char *word) { // --Done--
    
        // Searches the LinkedList for the input word and updates its frequency if found, and if not put it in first free position
        // Intended to be used as count(readWord())
    
        // Don't update if input is NULL
    
        if (word == NULL) {
            return;
        }
    
        // Check if first entry exists
    
        if (head == NULL) {
    
            Dict_entry* data_in = malloc(sizeof(Dict_entry));
    
            data_in->word = word;
            data_in->freq = 1;
    
            head = cons(data_in, NULL);
    
            return;
        }
    
        print_list(head, print_data);
    
        // Loop through words and update frequency if word is found
    
        Node* n = head;
    
        printf("\nLength of in-word: %d\n", strlen(word));
    
        while (n) { // while n not NULL
    
            if (match_by_word(n->data, word)) {
    
                printf("Word found: %s, updating freq\n", word);
                printf("Node pointer, Data pointer, next pointer: %p %p %p", n, n->data, n->next);
    
                ((Dict_entry*)n->data)->freq++;
    
                return;
    
            }
    
            n = n->next;
        }
    
        // If the word was not found, add it to words and set frequency
        printf("Adding word: %s\n", word);
    
        Dict_entry* data_in = malloc(sizeof(Dict_entry));
    
        data_in->word = word;
        data_in->freq = 1;
    
        addLast(head, cons(data_in, NULL)); // Add new node object
    
        return;
    
    }
    
    int main() {
    
        char* out_word;
    
        while ((out_word = readWord()) != NULL) {
            count(out_word);
        }
    
        printf("\nWaiting for input2");
        scanf("Wait for input");
    
        // Print the each word and frequency
    
        printf("\nWords and Frequencies:");
    
        print_list(head, print_data);
    
        // Free memory before termination
    
        Node* n = head;
    
        while (n) {
            Dict_entry* temp_data = (Dict_entry*)n->data;
    
            free(temp_data->word); // We MALLOCED these earlier
        }
    
        freeNodes(&head); // Frees entire LinkedList structure
    
    
        return 0;
    }
    There's some debug strings I've put in there. Everything seems to work well except the following. After exiting the first while-loop in the main() function my program crashes shortly after while still waiting for input from scanf(). I also have a scanf() that waits for input just before the final call of the readWord() function. Printing the LinkedList and everything works perfectly fine within the scope of the readWord() and count() functions. The moment when it steps outside (between my two scanf()s that I use to wait for input) it all collapses.

    I made a gif of the memory right between these two moments: Screen capture - b1b489f3ffe6fc8518132074ffc04806 - Gyazo

    If anybody has an insight into why the code crashes shortly after it exits the loop, I'd appreciate it greatly. Otherwise I'll have to work up a simpler solution.

    Edit: I forgot to mention that "head" is a global variable (the starting node of the linked list).
    Last edited by Himme; 12-11-2018 at 10:38 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,402
    What are the structs involved and what's the code for print_list?

    It would be better to post the smallest and simplest compilable program that demonstrates this error.

    (It is not important right now, but head should not be a global variable.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    779
    Just post a program we can run, not a bunch of code to stare at and a virtually meaningless movie. If that's how you use a debugger, looking at disassemblies and raw memory, then no wonder you're having a hard time!

    Anyway, your second use of your dubious scanf trick won't work since the newline that you entered to get out of the first one is still in the input buffer, so the second one is just passed by. Therefore the crash is apparently occurring in the print_list call after that (although undoubtedly the conditions for the crash were created before that).
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  4. #4
    Registered User
    Join Date
    Dec 2018
    Posts
    2
    Thanks for your replies. After taking laserlight's advice of succesively trying to cut the program down to the smallest constituents I found where the error seems to be (and as john.c stated using scanf() doesn't work to wait for input well). laserlight's signature quote is strong indeed. I didn't realize that it was so far down because the program never output its things that far. Otherwise, my print functions and other things worked out just fine.

    The error seems to be caused by the while-loop at the end trying to free() each word. I also forgot to make the loop actually advance to the next node in the list. The issue seems to stem from a bad string assignment in my function where I should instead use strcpy(), and thus I could not use free() on the char pointer anymore. (similar to this question FROM HERE that I found when minimizing the program: how do you free a string literal from memory?).

    By using strcpy() in that place everything worked out as it should and I could use free() properly. I was overwriting the malloc with something else when it was wrong.

    Thank you very much for your time and the good advice.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. if function not working (its inside anot if function)
    By ahahsiol in forum C Programming
    Replies: 2
    Last Post: 03-08-2013, 08:55 AM
  2. pointers and function calls inside a function
    By lexitron in forum C Programming
    Replies: 1
    Last Post: 12-03-2011, 05:43 PM
  3. Replies: 5
    Last Post: 04-15-2009, 02:47 PM
  4. Function/ifstream woes
    By Wraithan in forum C++ Programming
    Replies: 12
    Last Post: 12-03-2005, 04:05 PM
  5. Function calling woes
    By RedZippo in forum C Programming
    Replies: 6
    Last Post: 01-09-2004, 12:39 AM

Tags for this Thread