In Lab, we are working on linked list and i am at the point were i need to free
ID: 3815015 • Letter: I
Question
In Lab, we are working on linked list and i am at the point were i need to free the memory i used for my pointers variables and regular variables within my structs. I am able to free my pointer variables(the queue i think), but when I tried to implement the same procress to the regular variables within my struct named struct student_record(the nodes) i get a segmentation fault and i dont understand why. Please Help!!!
The File:
5 24 Dion Wills
2 17 Ashley Jackson
4 28 Ciara Brown
1 19 Zack Rench
3 21 Robert Morrison
My Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student_record
{
int student_id_;
int student_age_;
char first_name_[21];
char last_name_[21];
};
struct student_record_node
{
struct student_record* record_;
struct student_record_node* next_;
};
void parseFile(char* filename, struct student_record_node** head);
void printNode(struct student_record_node* node);
struct student_record_node* student_record_allocate();
void student_record_node_deallocate(struct student_record_node* node);
void sortByAge(struct student_record_node** recordsHead);
void sortById(struct student_record_node** recordsHead);
void swap(struct student_record_node** node1, struct student_record_node** node2);
void freeNodeList(struct student_record_node* head);
int main (int argc, char *argv[])
{
struct student_record_node* head = NULL;
char line[25];
if(argv[1] == NULL)
{
printf("ERROR: Missing File! ");
exit(0);
}
else
{
strcpy(line, argv[1]);
parseFile(line, &head);
}
return 0;
}
void parseFile(char* filename, struct student_record_node** head)
{
struct student_record_node* temp;
int i, id, age;
char firstName[25], lastName[25], line[25];
FILE *file = fopen(filename, "r");
*head = NULL;
while(fscanf(file, "%d%d%s%s", &id, &age, firstName, lastName) != EOF)
{
temp = student_record_allocate();
temp -> record_ = calloc(1, sizeof(struct student_record));
temp -> record_ -> student_id_ = id;
temp -> record_ -> student_age_ = age;
strcpy(temp -> record_ -> first_name_, firstName);
strcpy(temp -> record_ -> last_name_, lastName);
temp -> next_ = *head;
*head = temp;
}
printf("Before Sorting... ");
printNode(temp);
sortByAge(&temp);
printf(" After Sorting By Age... ");
printNode(temp);
sortById(&temp);
printf(" After Sorting By ID... ");
printNode(temp);
student_record_node_deallocate(temp); //HERE IS WERE I GET THE SEGMENTATION FAULT!
freeNodeList(temp);
fclose(file);
}
void printNode(struct student_record_node* node)
{
struct student_record_node* temp;
for(temp = node; temp != NULL; temp = temp -> next_)
{
printf("struct student_record_node: ");
printf(" Student First Name: %s ", temp -> record_ -> first_name_);
printf(" Student Last Name: %s ", temp -> record_ -> last_name_);
printf(" Student ID: %d ",temp -> record_ -> student_id_);
printf(" Student Age: %d ", temp -> record_ -> student_age_);
}
}
struct student_record_node* student_record_allocate()
{
struct student_record_node* mem = calloc(1, sizeof(struct student_record_node));
mem -> record_ = 0;
mem -> next_ = NULL;
return mem;
}
void student_record_node_deallocate(struct student_record_node* node) //HERE IS THE FUNCTION IM HAVING TROUBLE WITH
{
struct student_record_node* deallocate;
while(node != NULL)
{
deallocate -> record_ = node -> record_;
node -> record_ = node -> next_ -> record_;
free(deallocate -> record_);
printf("Free Var!!! ");
}
}
void sortByAge(struct student_record_node** recordsHead)
{
struct student_record_node* sort;
struct student_record_node* temp = NULL;
int swapped, i;
do
{
swapped = 0;
sort = *recordsHead;
while (sort -> next_ != NULL)
{
if (sort -> record_ -> student_age_ > sort -> next_ -> record_ -> student_age_)
{
swap(&sort, &sort -> next_);
swapped = 1;
}
sort = sort -> next_;
}
temp = sort;
}while(swapped);
}
void sortById(struct student_record_node** recordsHead)
{
struct student_record_node* sort;
struct student_record_node* temp = NULL;
int swapped, i;
do
{
swapped = 0;
sort = *recordsHead;
while (sort -> next_ != NULL)
{
if (sort -> record_ -> student_id_ > sort -> next_ -> record_ -> student_id_)
{
swap(&sort, &sort -> next_);
swapped = 1;
}
sort = sort -> next_;
}
temp = sort;
}while(swapped);
}
void swap(struct student_record_node** node1, struct student_record_node** node2)
{
struct student_record* temp;
struct student_record_node* n1;
struct student_record_node* n2;
n1 = *node1;
n2 = *node2;
temp = n1 -> record_ ;
n1 -> record_ = n2 -> record_ ;
n2 -> record_ = temp;
}
void freeNodeList(struct student_record_node* head)
{
struct student_record_node* freeList;
while (head != NULL)
{
freeList = head;
head = head -> next_;
free(freeList);
printf("Free Pointer!! ");
}
}
Explanation / Answer
Two things to note here for better understanding
student_record_node_deallocate(temp); //HERE IS WERE I GET THE SEGMENTATION FAULT!
freeNodeList(temp);
In this firstly you are trying to free a variable and then you are trying to access lsit held by that variable and freeing it. It will never work and order should always be reverse, i.e., first free whatever that variable contain and then free itself.
Secondly always see that you are freeing only what you asked for explictly and in that exact reverse order.
So lets see what does student_record_node_deallocate is doing
This function is going over list and deallocating all the student_record_node element but then we have one method which is deallocating list itself (freeNodeList). So I will say repurpose this to delocate memory for student_record and call that from free node to free that _record variable only for that node and then deallocate memory for the node itself.
void student_record_node_deallocate(struct student_record_node* node)
{
struct student_record_node* deallocate;
while(node != NULL)
{
deallocate -> record_ = node -> record_;
node -> record_ = node -> next_ -> record_;
free(deallocate -> record_);
printf("Free Var!!! ");
}
}
So this function will change to
void student_record_node_deallocate(struct student_record_node* node)
{
free(node-> record_);
printf("Free Var in student_record_node_deallocate!!! ");
}
and freeNodeList will change to
void freeNodeList(struct student_record_node* head)
{
struct student_record_node* freeList;
while (head != NULL)
{
freeList = head;
head = head -> next_;
student_record_node_deallocate(freeList);
free(freeList);
printf("Free Pointer in freeNodeList!! ");
}
}
(Please rename function if you want to)
Here is full code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student_record
{
int student_id_;
int student_age_;
char first_name_[21];
char last_name_[21];
};
struct student_record_node
{
struct student_record* record_;
struct student_record_node* next_;
};
void parseFile(char* filename, struct student_record_node** head);
void printNode(struct student_record_node* node);
struct student_record_node* student_record_allocate();
void student_record_node_deallocate(struct student_record_node* node);
void sortByAge(struct student_record_node** recordsHead);
void sortById(struct student_record_node** recordsHead);
void swap(struct student_record_node** node1, struct student_record_node** node2);
void freeNodeList(struct student_record_node* head);
int main (int argc, char *argv[])
{
struct student_record_node* head = NULL;
char line[25];
if(argv[1] == NULL)
{
printf("ERROR: Missing File! ");
exit(0);
}
else
{
strcpy(line, argv[1]);
parseFile(line, &head);
}
return 0;
}
void parseFile(char* filename, struct student_record_node** head)
{
struct student_record_node* temp;
int i, id, age;
char firstName[25], lastName[25], line[25];
FILE *file = fopen(filename, "r");
*head = NULL;
while(fscanf(file, "%d%d%s%s", &id, &age, firstName, lastName) != EOF)
{
temp = student_record_allocate();
temp -> record_ = calloc(1, sizeof(struct student_record));
temp -> record_ -> student_id_ = id;
temp -> record_ -> student_age_ = age;
strcpy(temp -> record_ -> first_name_, firstName);
strcpy(temp -> record_ -> last_name_, lastName);
temp -> next_ = *head;
*head = temp;
}
printf("Before Sorting... ");
printNode(temp);
sortByAge(&temp);
printf(" After Sorting By Age... ");
printNode(temp);
sortById(&temp);
printf(" After Sorting By ID... ");
printNode(temp);
freeNodeList(temp);
// student_record_node_deallocate(temp); //HERE IS WERE I GET THE SEGMENTATION FAULT!
// freeNodeList(temp);
fclose(file);
}
void printNode(struct student_record_node* node)
{
struct student_record_node* temp;
for(temp = node; temp != NULL; temp = temp -> next_)
{
printf("struct student_record_node: ");
printf(" Student First Name: %s ", temp -> record_ -> first_name_);
printf(" Student Last Name: %s ", temp -> record_ -> last_name_);
printf(" Student ID: %d ",temp -> record_ -> student_id_);
printf(" Student Age: %d ", temp -> record_ -> student_age_);
}
}
struct student_record_node* student_record_allocate()
{
struct student_record_node* mem = calloc(1, sizeof(struct student_record_node));
mem -> record_ = 0;
mem -> next_ = NULL;
return mem;
}
void student_record_node_deallocate(struct student_record_node* node) //HERE IS THE FUNCTION IM HAVING TROUBLE WITH
{
free(node-> record_);
printf("Free Var in student_record_node_deallocate!!! ");
}
void sortByAge(struct student_record_node** recordsHead)
{
struct student_record_node* sort;
struct student_record_node* temp = NULL;
int swapped, i;
do
{
swapped = 0;
sort = *recordsHead;
while (sort -> next_ != NULL)
{
if (sort -> record_ -> student_age_ > sort -> next_ -> record_ -> student_age_)
{
swap(&sort, &sort -> next_);
swapped = 1;
}
sort = sort -> next_;
}
temp = sort;
}while(swapped);
}
void sortById(struct student_record_node** recordsHead)
{
struct student_record_node* sort;
struct student_record_node* temp = NULL;
int swapped, i;
do
{
swapped = 0;
sort = *recordsHead;
while (sort -> next_ != NULL)
{
if (sort -> record_ -> student_id_ > sort -> next_ -> record_ -> student_id_)
{
swap(&sort, &sort -> next_);
swapped = 1;
}
sort = sort -> next_;
}
temp = sort;
}while(swapped);
}
void swap(struct student_record_node** node1, struct student_record_node** node2)
{
struct student_record* temp;
struct student_record_node* n1;
struct student_record_node* n2;
n1 = *node1;
n2 = *node2;
temp = n1 -> record_ ;
n1 -> record_ = n2 -> record_ ;
n2 -> record_ = temp;
}
void freeNodeList(struct student_record_node* head)
{
struct student_record_node* freeList;
while (head != NULL)
{
freeList = head;
head = head -> next_;
student_record_node_deallocate(freeList);
free(freeList);
printf("Free Pointer in freeNodeList!! ");
}
}
Please leave positive rating if you feel this has helped you understand issue and I have fixed the issue.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.