handle failed memory allocation
This commit is contained in:
6 files changed
+38
-6
No files matched your search
@@ -33,4 +33,6 @@
|
|||||||
|
|
||||||
static const char FLEX[][11] = {"XAT--12A-S", "XAT--12B-S"};
|
static const char FLEX[][11] = {"XAT--12A-S", "XAT--12B-S"};
|
||||||
|
|
||||||
|
void handle(void* mem, char name[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -33,6 +33,7 @@ UNIQUE_COURSES getNumberOfCourses(CSV_LINE *lines, size_t lines_len) {
|
|||||||
|
|
||||||
COURSE *getCourses(CSV_LINE *lines, size_t lines_len, UNIQUE_COURSES unique_course_info) {
|
COURSE *getCourses(CSV_LINE *lines, size_t lines_len, UNIQUE_COURSES unique_course_info) {
|
||||||
COURSE *courses = malloc(unique_course_info.numberOfCourses * sizeof(COURSE));
|
COURSE *courses = malloc(unique_course_info.numberOfCourses * sizeof(COURSE));
|
||||||
|
handle(courses, "'courses' from getCourses");
|
||||||
for (size_t i = 0; i < unique_course_info.numberOfCourses; i++) {
|
for (size_t i = 0; i < unique_course_info.numberOfCourses; i++) {
|
||||||
for (size_t j = 0; j < lines_len; j++) {
|
for (size_t j = 0; j < lines_len; j++) {
|
||||||
if (strcmp(lines[j].crsNo, unique_course_info.uniqueCrsNos[j]) == 0) {
|
if (strcmp(lines[j].crsNo, unique_course_info.uniqueCrsNos[j]) == 0) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ CSV_LINE *csvReader(char data_dir[], size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CSV_LINE *lines = malloc(size * sizeof(CSV_LINE));
|
CSV_LINE *lines = malloc(size * sizeof(CSV_LINE));
|
||||||
|
handle(lines, "'lines' from csvReader");
|
||||||
|
|
||||||
char buff[MAX_CHAR];
|
char buff[MAX_CHAR];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
+23
-5
@@ -68,6 +68,8 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
/*** STEP 1 - Tally requests to check which courses are eligable to run ***/
|
/*** STEP 1 - Tally requests to check which courses are eligable to run ***/
|
||||||
char **activeCourses = malloc(MAX_CLASSES * sizeof(char *));
|
char **activeCourses = malloc(MAX_CLASSES * sizeof(char *));
|
||||||
uint16_t *activeCoursesIndexes = malloc(MAX_CLASSES * sizeof(uint16_t));
|
uint16_t *activeCoursesIndexes = malloc(MAX_CLASSES * sizeof(uint16_t));
|
||||||
|
handle(activeCourses, "'activeCourses' from generateTimetable");
|
||||||
|
handle(activeCoursesIndexes, "'activeCoursesIndexes' from generateTimetable");
|
||||||
uint16_t activeCoursesLen = 0; // also acts as the length of activeCourses
|
uint16_t activeCoursesLen = 0; // also acts as the length of activeCourses
|
||||||
for (size_t i = 0; i < size_students; i++) {
|
for (size_t i = 0; i < size_students; i++) {
|
||||||
for (size_t j = 0; j < students[i].requestsLen; j++) {
|
for (size_t j = 0; j < students[i].requestsLen; j++) {
|
||||||
@@ -79,6 +81,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
if (courses[k].requests >= MIN_REQ) {
|
if (courses[k].requests >= MIN_REQ) {
|
||||||
if (activeCoursesLen == 0) {
|
if (activeCoursesLen == 0) {
|
||||||
activeCourses[activeCoursesLen] = malloc(sizeof(char) * MAX_COURSE_NO_LEN);
|
activeCourses[activeCoursesLen] = malloc(sizeof(char) * MAX_COURSE_NO_LEN);
|
||||||
|
handle(activeCourses[activeCoursesLen], "'activeCourses[idx]' from generateTimetable");
|
||||||
strcpy(activeCourses[activeCoursesLen], courses[k].crsNo);
|
strcpy(activeCourses[activeCoursesLen], courses[k].crsNo);
|
||||||
activeCoursesIndexes[activeCoursesLen] = k;
|
activeCoursesIndexes[activeCoursesLen] = k;
|
||||||
activeCoursesLen++;
|
activeCoursesLen++;
|
||||||
@@ -93,6 +96,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
|
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
activeCourses[activeCoursesLen] = malloc(sizeof(char) * MAX_COURSE_NO_LEN);
|
activeCourses[activeCoursesLen] = malloc(sizeof(char) * MAX_COURSE_NO_LEN);
|
||||||
|
handle(activeCourses[activeCoursesLen], "'activeCourses[idx]' from generateTimetable");
|
||||||
strcpy(activeCourses[activeCoursesLen], courses[k].crsNo);
|
strcpy(activeCourses[activeCoursesLen], courses[k].crsNo);
|
||||||
activeCoursesIndexes[activeCoursesLen] = k;
|
activeCoursesIndexes[activeCoursesLen] = k;
|
||||||
activeCoursesLen++;
|
activeCoursesLen++;
|
||||||
@@ -111,6 +115,8 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
uint8_t *allClassRunCounts = malloc(activeCoursesLen * sizeof(uint8_t));
|
uint8_t *allClassRunCounts = malloc(activeCoursesLen * sizeof(uint8_t));
|
||||||
// max this out to total number of classrooms available between both semesters
|
// max this out to total number of classrooms available between both semesters
|
||||||
CLASS *classes = malloc(CLASSROOMS * TOTAL_BLOCKS * sizeof(CLASS));
|
CLASS *classes = malloc(CLASSROOMS * TOTAL_BLOCKS * sizeof(CLASS));
|
||||||
|
handle(allClassRunCounts, "'allClassRunCounts' from generateTimetable");
|
||||||
|
handle(classes, "'classes' from generateTimetable");
|
||||||
size_t classesLen = 0;
|
size_t classesLen = 0;
|
||||||
for (size_t i = 0; i < activeCoursesLen; i++) {
|
for (size_t i = 0; i < activeCoursesLen; i++) {
|
||||||
uint16_t index = activeCoursesIndexes[i];
|
uint16_t index = activeCoursesIndexes[i];
|
||||||
@@ -119,6 +125,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
|
|
||||||
// add 1 to classRunCount in case we need to create an extra class with remaining
|
// add 1 to classRunCount in case we need to create an extra class with remaining
|
||||||
size_t *courseClassIndexes = malloc((classRunCount + 1) * sizeof(size_t));
|
size_t *courseClassIndexes = malloc((classRunCount + 1) * sizeof(size_t));
|
||||||
|
handle(courseClassIndexes, "'courseClassIndexes' from generateTimetable");
|
||||||
for (size_t j = 0; j < classRunCount; j++) {
|
for (size_t j = 0; j < classRunCount; j++) {
|
||||||
CLASS newClass;
|
CLASS newClass;
|
||||||
strcpy(newClass.baseCrsNo, courses[index].crsNo);
|
strcpy(newClass.baseCrsNo, courses[index].crsNo);
|
||||||
@@ -175,6 +182,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
classRunCount++;
|
classRunCount++;
|
||||||
if (classRunCount >= 2) {
|
if (classRunCount >= 2) {
|
||||||
uint8_t *numberOfStudentsArr = malloc(classRunCount * sizeof(uint8_t));
|
uint8_t *numberOfStudentsArr = malloc(classRunCount * sizeof(uint8_t));
|
||||||
|
handle(numberOfStudentsArr, "'numberOfStudentsArr' from generateTimetable");
|
||||||
for (size_t j = 0; j < classRunCount; j++)
|
for (size_t j = 0; j < classRunCount; j++)
|
||||||
numberOfStudentsArr[j] = classes[courseClassIndexes[j]].numberOfStudents;
|
numberOfStudentsArr[j] = classes[courseClassIndexes[j]].numberOfStudents;
|
||||||
|
|
||||||
@@ -213,6 +221,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
|
|
||||||
// Equalize the class number of students
|
// Equalize the class number of students
|
||||||
uint8_t *numberOfStudentsArr = malloc(classRunCount * sizeof(uint8_t));
|
uint8_t *numberOfStudentsArr = malloc(classRunCount * sizeof(uint8_t));
|
||||||
|
handle(numberOfStudentsArr, "'numberOfStudentsArr' from generateTimetable");
|
||||||
for (size_t j = 0; j < classRunCount; j++)
|
for (size_t j = 0; j < classRunCount; j++)
|
||||||
numberOfStudentsArr[j] = classes[courseClassIndexes[j]].numberOfStudents;
|
numberOfStudentsArr[j] = classes[courseClassIndexes[j]].numberOfStudents;
|
||||||
|
|
||||||
@@ -250,21 +259,24 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
}
|
}
|
||||||
|
|
||||||
// realloc classes to correct size
|
// realloc classes to correct size
|
||||||
CLASS *tempclasses = malloc(classesLen * sizeof(CLASS));
|
CLASS *tempClasses = malloc(classesLen * sizeof(CLASS));
|
||||||
|
handle(tempClasses, "'tempClasses' from generateTimetable");
|
||||||
for (size_t i = 0; i < classesLen; i++)
|
for (size_t i = 0; i < classesLen; i++)
|
||||||
tempclasses[i] = classes[i];
|
tempClasses[i] = classes[i];
|
||||||
classes = realloc(classes, classesLen * sizeof(CLASS));
|
classes = realloc(classes, classesLen * sizeof(CLASS));
|
||||||
memcpy(classes, tempclasses, classesLen * sizeof(CLASS));
|
memcpy(classes, tempClasses, classesLen * sizeof(CLASS));
|
||||||
free(tempclasses);
|
free(tempClasses);
|
||||||
free(activeCoursesIndexes);
|
free(activeCoursesIndexes);
|
||||||
|
|
||||||
|
|
||||||
/*** STEP 3 - Insert students into empty classes ***/
|
/*** STEP 3 - Insert students into empty classes ***/
|
||||||
STUDENT *tempStudents = malloc(size_students * sizeof(STUDENT));
|
STUDENT *tempStudents = malloc(size_students * sizeof(STUDENT));
|
||||||
|
handle(tempStudents, "'tempStudents' from generateTimetable");
|
||||||
size_t size_tempStudents = size_students;
|
size_t size_tempStudents = size_students;
|
||||||
memcpy(tempStudents, students, size_students * sizeof(STUDENT));
|
memcpy(tempStudents, students, size_students * sizeof(STUDENT));
|
||||||
|
|
||||||
uint8_t *currentInserted = malloc(classesLen * sizeof(uint8_t));
|
uint8_t *currentInserted = malloc(classesLen * sizeof(uint8_t));
|
||||||
|
handle(currentInserted, "'currentInserted' from generateTimetable");
|
||||||
for (size_t i = 0; i < classesLen; i++)
|
for (size_t i = 0; i < classesLen; i++)
|
||||||
currentInserted[i] = 0;
|
currentInserted[i] = 0;
|
||||||
|
|
||||||
@@ -279,6 +291,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
numberOfAlts++;
|
numberOfAlts++;
|
||||||
|
|
||||||
REQUEST *alternates = malloc(numberOfAlts * sizeof(REQUEST));
|
REQUEST *alternates = malloc(numberOfAlts * sizeof(REQUEST));
|
||||||
|
handle(alternates, "'alternates' from generateTimetable");
|
||||||
size_t alternateIdx = 0;
|
size_t alternateIdx = 0;
|
||||||
for (size_t i = 0; i < student.requestsLen; i++) {
|
for (size_t i = 0; i < student.requestsLen; i++) {
|
||||||
if (student.requests[i].alternate) {
|
if (student.requests[i].alternate) {
|
||||||
@@ -321,6 +334,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
|
|
||||||
// remove alternate from array of alts to retry same alt over and over
|
// remove alternate from array of alts to retry same alt over and over
|
||||||
REQUEST *tempAlternates = malloc(numberOfAlts * sizeof(REQUEST));
|
REQUEST *tempAlternates = malloc(numberOfAlts * sizeof(REQUEST));
|
||||||
|
handle(tempAlternates, "'tempAlternates' from generateTimetable");
|
||||||
memcpy(tempAlternates, alternates, numberOfAlts * sizeof(REQUEST));
|
memcpy(tempAlternates, alternates, numberOfAlts * sizeof(REQUEST));
|
||||||
numberOfAlts--;
|
numberOfAlts--;
|
||||||
|
|
||||||
@@ -347,6 +361,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
strcpy(course, alternates[0].crsNo); // asign alternate to course and retry
|
strcpy(course, alternates[0].crsNo); // asign alternate to course and retry
|
||||||
// remove alternate from array of alts to retry same alt over and over
|
// remove alternate from array of alts to retry same alt over and over
|
||||||
REQUEST *tempAlternates = malloc(numberOfAlts * sizeof(REQUEST));
|
REQUEST *tempAlternates = malloc(numberOfAlts * sizeof(REQUEST));
|
||||||
|
handle(tempAlternates, "'tempAlternates' from generateTimetable");
|
||||||
memcpy(tempAlternates, alternates, numberOfAlts * sizeof(REQUEST));
|
memcpy(tempAlternates, alternates, numberOfAlts * sizeof(REQUEST));
|
||||||
numberOfAlts--;
|
numberOfAlts--;
|
||||||
alternates = realloc(alternates, numberOfAlts * sizeof(REQUEST));
|
alternates = realloc(alternates, numberOfAlts * sizeof(REQUEST));
|
||||||
@@ -382,6 +397,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
// realloc tempStudents to be size_tempStudents - 1 without struct of student just processed
|
// realloc tempStudents to be size_tempStudents - 1 without struct of student just processed
|
||||||
size_tempStudents--;
|
size_tempStudents--;
|
||||||
STUDENT *new_tempStudents = malloc(size_tempStudents * sizeof(STUDENT));
|
STUDENT *new_tempStudents = malloc(size_tempStudents * sizeof(STUDENT));
|
||||||
|
handle(new_tempStudents, "'new_tempStudents' from generateTimetable");
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (size_t i = 0; i <= size_tempStudents; i++) {
|
for (size_t i = 0; i <= size_tempStudents; i++) {
|
||||||
if (tempStudents[i].pupilNum != student.pupilNum) {
|
if (tempStudents[i].pupilNum != student.pupilNum) {
|
||||||
@@ -501,6 +517,8 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
// create temp arrays of data
|
// create temp arrays of data
|
||||||
uint8_t *tempAllClassRunCounts = malloc(activeCoursesLen * sizeof(uint8_t));
|
uint8_t *tempAllClassRunCounts = malloc(activeCoursesLen * sizeof(uint8_t));
|
||||||
char **tempActiveCourses = malloc(activeCoursesLen * sizeof(char*));
|
char **tempActiveCourses = malloc(activeCoursesLen * sizeof(char*));
|
||||||
|
handle(tempAllClassRunCounts, "'tempAllClassRunCounts' from generateTimetable");
|
||||||
|
handle(tempActiveCourses, "'tempActiveCourses' from generateTimetable");
|
||||||
|
|
||||||
// Copy data without the course we just handled
|
// Copy data without the course we just handled
|
||||||
size_t tempIndex = 0;
|
size_t tempIndex = 0;
|
||||||
@@ -540,7 +558,7 @@ TIMETABLE generateTimetable(STUDENT *students, size_t size_students, COURSE *cou
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// STEP 6 - most complex something
|
// STEP 6 - Solve student schedule errors
|
||||||
|
|
||||||
|
|
||||||
free(classes);
|
free(classes);
|
||||||
|
|||||||
+8
-1
@@ -11,7 +11,14 @@
|
|||||||
#include "../include/json.h"
|
#include "../include/json.h"
|
||||||
#include "../include/generator.h"
|
#include "../include/generator.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
void handle(void *mem, char name[]) {
|
||||||
|
if (mem == NULL) {
|
||||||
|
fprintf(stderr, "Failed to allocate memory! - Memory: %s\n", name);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
/*
|
/*
|
||||||
read csv data into array of structs that can
|
read csv data into array of structs that can
|
||||||
be processed into an array of student structs
|
be processed into an array of student structs
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ STUDENT *getStudents(CSV_LINE *lines, size_t lines_len, int total_blocks, UNIQUE
|
|||||||
|
|
||||||
// Create our student array with the correct number of students
|
// Create our student array with the correct number of students
|
||||||
STUDENT *students = malloc(students_info.numberOfStudents * sizeof(STUDENT));
|
STUDENT *students = malloc(students_info.numberOfStudents * sizeof(STUDENT));
|
||||||
|
handle(students, "'students' from getStudents");
|
||||||
for (uint16_t i = 0; i < students_info.numberOfStudents; i++) {
|
for (uint16_t i = 0; i < students_info.numberOfStudents; i++) {
|
||||||
STUDENT student;
|
STUDENT student;
|
||||||
|
|
||||||
@@ -51,12 +52,14 @@ STUDENT *getStudents(CSV_LINE *lines, size_t lines_len, int total_blocks, UNIQUE
|
|||||||
student.remainingAltsLen = 0;
|
student.remainingAltsLen = 0;
|
||||||
|
|
||||||
REQUEST *requests = malloc(numRequests[i] * sizeof(REQUEST));
|
REQUEST *requests = malloc(numRequests[i] * sizeof(REQUEST));
|
||||||
|
handle(requests, "'requests' from getStudents");
|
||||||
student.requests = requests;
|
student.requests = requests;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < TOTAL_BLOCKS; i++)
|
for (uint8_t i = 0; i < TOTAL_BLOCKS; i++)
|
||||||
strcpy(student.schedule[i], i < TOTAL_BLOCKS / 2 ? FLEX[0] : FLEX[1]);
|
strcpy(student.schedule[i], i < TOTAL_BLOCKS / 2 ? FLEX[0] : FLEX[1]);
|
||||||
|
|
||||||
REQUEST *remainingAlts = malloc(MAX_REQUEST_ALTS * sizeof(REQUEST));
|
REQUEST *remainingAlts = malloc(MAX_REQUEST_ALTS * sizeof(REQUEST));
|
||||||
|
handle(remainingAlts, "'remainingAlts' from getStudents");
|
||||||
student.remainingAlts = remainingAlts;
|
student.remainingAlts = remainingAlts;
|
||||||
|
|
||||||
students[i] = student;
|
students[i] = student;
|
||||||
|
|||||||
Reference in new issue
Block a user