I am building a Student Management System and it has to make use of linked lists.
One of the requirements is that each student has to have a list of courses that they are enrolled in. To handle that I implemented 2 separate linked lists and then joined them where necessary. But when executing the printList
function, only the last student entered gets output and then the above mentioned error code appears. Additionally, I tried running the code in an online compiler and it worked fine, any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Structures creation
typedef struct course {
char courseName[40];
int credits;
struct course *nextCourse;
} course;
typedef struct student {
char firstName[50];
char lastName[50];
int age;
char address[100];
char progName[60];
course *courseList;
struct student *next;
} student;
void *checkMalloc(size_t num_bytes);
void addStudent(student **headStd, char *fName, char *lName, int age, char *address, char *progName);
void addCourse(student *currStd, char *cName, int cred);
void printList(student *first);
int main() {
student *headStd = NULL;
addStudent(&headStd, "John", "Doe", 19, "Lot 123", "Comp Sci");
addCourse(headStd, "CSE2100", 4);
addCourse(headStd, "CSE2101", 4);
addStudent(&headStd, "Jane", "Smith", 20, "Lot 3 East Street", "Info Sys");
addCourse(headStd, "ISY2100", 4);
addCourse(headStd, "ITE2101", 3);
printList(headStd);
return EXIT_SUCCESS;
}
void addStudent(student **headStd, char *fName, char *lName, int age, char *address, char *progName) {
student *newStd = checkMalloc(sizeof(*newStd));
strcpy(newStd->firstName, fName);
strcpy(newStd->lastName, lName);
newStd->age = age;
strcpy(newStd->address, address);
strcpy(newStd->progName, progName);
// This line was missing in the original code posted
// newStd->courseList = NULL;
newStd->next = (*headStd);
(*headStd) = newStd;
}
void addCourse(student *currStd, char *cName, int cred) {
//Memory allocation
course *newCourse = checkMalloc(sizeof(*newCourse));
strcpy(newCourse->courseName, cName);
newCourse->credits = cred;
newCourse->nextCourse = currStd->courseList;
currStd->courseList = newCourse;
}
void printList(student *first) {
while (first != NULL) {
printf("Name: %s %s\n", first->firstName, first->lastName);
printf("Age: %d\n", first->age);
printf("Address: %s\n", first->address);
printf("Program Enrolled: %s\n", first->progName);
course *currCourse = first->courseList;
if (currCourse == NULL) {
printf("\tNo Courses Present\n");
} else {
while (currCourse != NULL) {
printf("\tCourse Name: %s\n", currCourse->courseName);
printf("\tCourse Credits: %d\n", currCourse->credits);
currCourse = currCourse->nextCourse;
}
}
first = first->next;
}
}
void *checkMalloc(size_t num_bytes) {
void *memory = malloc(num_bytes);
if (memory == NULL) {
printf("Error, couldn't allocate memory.\n");
exit(-1);
}
return memory;
}
CodePudding user response:
In the code you posted, the member newStd->courseList
is not initialized by the function addStudent
. Since the memory is allocated with malloc
, its contents is indeterminate, meaning the pointer courseList
might be an invalid pointer.
You then insert a list of courses before this invalid pointer... The same happens for the second student... invalid pointers there have not been dereferenced, but are waiting to bite like poison snakes.
When you print the student details and the list of courses, after the last course the line currCourse = currCourse->nextCourse;
reads the invalid pointer into currCourse
and the next iteration will crash when dereferencing this pointer.
This explains the observed behavior, but this undefined behavior is not guaranteed to be observable as malloc
may also return memory that happens to be filled with all bits zero, so the initial value of newStd->courseList
could be a null pointer.
The fix is simple: add newStd->courseList = NULL;
in addStudent()
.
CodePudding user response:
The problem is that you do not allocate enough memory with malloc
. You pass the uninitialised variable, but you should better pass the number of bytes needed for the struct.
So change:
checkMalloc(sizeof(*newStd));
to
checkMalloc(sizeof(student));
And do the same for the courses.