I am having some trouble running this linked list implementation (containing words as data). Problem is when I try to print the words (that I inserted) in the Linked List,I get nothing. What am I doing wrong, breaking my head over this? I hope it’s not something silly. Anyway here’s the code –
typedef struct node
{
void *data;
struct node *next;
} NODE;
NODE *new_node(void *data)
{
NODE *new = malloc(sizeof(NODE));
if(new)
{
new->data = data;
new->next = NULL;
return new;
}
else
{
return NULL;
}
}
void print_list(NODE *head, void (print_fn) (void*))
{
if(head && head->next)
{
while(head->next)
{
if(print_fn)
print_fn(head->data);
else
printf("Word: %s\n", (char *)head->data);
head = head->next;
}
}
return;
}
void append(NODE **head, NODE *node)
{
NODE *tmp = *head;
if(tmp && node)
{
while(tmp->next)
tmp = tmp->next;
(*head)->next = node; /*add as last node*/
}
return;
}
NODE *create_list()
{
FILE *dict_file = fopen("trial.txt", "r");
if(dict_file)
{
NODE *head = new_node(NULL);
if(!head) return NULL;
char word[20];
int first = TRUE;
memset(word, '\0', 20);
while(fgets(word, sizeof(word), dict_file) != NULL )
{
if(first)
{
head->data = (void*)word;
first = FALSE;
}
else
{
append(&head, new_node((void*)word));
}
}
fclose(dict_file);
return head;
}
else
{
printf("ERROR: File not found");
return NULL;
}
}
int main(int argc, char *argv[])
{
NODE *head = create_list();
if(!head)
{
printf("ERROR: Either malloc() failed or data not found\n");
return FALSE;
}
else
{
print_list(head, NULL);
return TRUE;
}
}
This has become quite a long answer. Don’t take this personally, but you have made quite a few rookie mistakes. I have met with many people at university whom I helped to learn the C language and programming in general, so I’ve got used to notice these kinds of things.
The important issues I could find
You assign a pointer to a stack variable to
wordsThis is completely bad, because that value will be overwritten once the execution gets out of the function that creates it. Solution: copy the content of that variable into a heap variable.
Your
appendfunction is faultyIt adds the appended element to the second place instead of the last place. Note that you don’t need the return at the end either. There is also no point in requiring a double-pointer as input to the
appendmethod. Also, after assigningheadtotmp, it is futile to check tmp againstNULLas well, since it won’t beNULLifheadisn’tNULL. Also, I recommend checking the new node againstNULLas well. If it isNULL, this saves you from iterating over the entire collection.The
create_listfunction is sub-optimalFist, the distinction between the first and the other cases are futile. Introducing another pointer (called
currentin my code) will eliminate the need to check whether it is the first or not. Next, you always call theappendfunction on thehead, thus you always need to iterate over the entire collection. This can be also optimized by introducing thecurrentvariable. (Which, at start, should be assigned the value ofhead.)The
print_listfunction is errornousIt doesn’t print anything if there is only one node. It also redundantly checks the pointers for null. (The beginning of the loop checks it, too.) The return statement at the end of this
voidfunction is also unnecessary.You should free up memory when you don’t use it
@Baltasarq wrote a nice
clearfunction in his answer, you should use it. 🙂Not serious errors, but you should be aware of them
You should not use
void*instead ofchar*If you know that the
datamember of theNODEstructure is going to store characters, why do you usevoid*? It is bad practice! (Unless you have a good reason, of course.)Using the
newword as a variable name makes your code not compliant with C++. Thus, I recommend against it.Adopt a better coding style, please – it will make your code so much easier to read
Inconsistency: if in
print_listyou don’t allocate a new variable to go through the collection (like you do with thetmpvariable inappend) then it is misguiding to name the parameter ashead. (I renamed it tonodein my code.)Here is the fixed code
(Note that there may be small syntax errors because I typed the code into the browser without actually testing it.)