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).