Reputation: 105
I'm suppose to implement QuickSort on a linked list, but I'm having trouble reading from text file into the list and printing all the nodes. I only get the last element printed as Output. What am I doing wrong?
My text file looks like this (password and its usage frequency):
asdfgh 31554
snoopy1 15637
qwertyuiop 24372
soccer 21208
.
.
Here's my structs
struct list_element {
char *password;
int count;
list_element* next;
};
struct list {
list_element* first;
list_element* last;
};
ReadfromData()
void read_data(char* filename, list* mylist)
{
FILE *fp;
char password[128];
int freq;
fp = fopen(filename, "r");
if(fp == NULL)
{
perror("Error opening file");
return;
}
while(fgets(password, sizeof(password), fp))
{
list_element *node = malloc(sizeof(list_element));
char *token;
token = strtok(password, " ");
node->password = strdup(token);
if( token != NULL ){
token = strtok(NULL, " ");
}
freq = atoi(token);
node->count = freq;
node->next = NULL;
insert_list(node, mylist);
}
fclose(fp);
}
Insert infront in List
void insert_list(list_element* le, list* mylist)
if((mylist->first = NULL)){
mylist->first = le;
}else{
le->next = mylist->first;
mylist->first = le;
}
Print list
void print_list(list* mylist)
list_element *temp;
temp = mylist->first;
while(temp != NULL)
{
printf("pass %s and count %d \n", temp->password, temp->count);
temp = temp->next;
}
I've also wrote a small function, which I call in the beginning of the program to intailize the list:
void init_list(list* mylist){
mylist = (list*)malloc(sizeof(list));
mylist->first = mylist->last = NULL;
}
but I don't think it makes sense to do a malloc here too, since I already create node one by one, right? Confused abit.
Any advice would be great!
Upvotes: 0
Views: 1414
Reputation: 409482
Lets take a closer look at the init_list
function:
void init_list(list* mylist){
mylist = (list*)malloc(sizeof(list));
mylist->first = mylist->last = NULL;
}
The argument mylist
is a local variable. And as such it will go out of scope when the function ends and all changes to it will be lost. Because of this the pointer you will be using after the call to init_list
will not actually be initialized and you will have undefined behavior when you use it.
There are two solutions: Either have init_list
take no argument and instead return the new list. Or you emulate pass by value by passing a pointer to the list variable from the calling function, meaning the init_list
function takes a pointer to a pointer to the structure.
The second alternative could look like this
void init_list(list **mylist)
{
*mylist = malloc(sizeof **mylist);
(*mylist)->first = (*mylist)->last = NULL;
}
Then you call it using the address-of operator:
list *mylist;
init_list(&mylist);
Upvotes: 1