Getting a segmentation fault in my code. - c

When trying to run my program on Linux I get a segmentation fault. I am a novice with C. In doing research, I figure the reason is probably a loop running beyond the last index in one of the arrays and accessing memory it shouldn't. Any hints?
Program overview: takes in a file in a certain format and determines from that file that best place to eat at based on the voter's three top favorites and least favorite.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int outputToFile (int winner, char **restaurantList, char **voterNameList, int numberOfVoters, int **voterFavorites) {
int index;
FILE *output;
output = fopen ("output_1", "w"); //write mode
fprintf(output, "%s\n", restaurantList[winner]); // write out the winning restuarant
fprintf(output, "Happy:\n");
for (index = 0; index < numberOfVoters ; index++) { // write out the happy persons
if (voterFavorites[index][1] == winner || voterFavorites[index][2] == winner || voterFavorites[index][3] == winner) {
fprintf(output, "%s\n", voterNameList[index]);
}
}
fprintf (output, "Sad:\n");
for (index = 0; index < numberOfVoters ; index++) { // write out the sad persons
if (voterFavorites[index][4] == winner) {
fprintf(output, "%s\n", voterNameList[index]);
}
}
fclose (output);
}
int countScore (int **voterFavorites, int tallyCard[], int numberOfVoters, int numberOfRestaurants) {
int index;
for (index = 0; index < numberOfRestaurants; index++ ) {
tallyCard[index] = 0;
}
for (index = 0; index < numberOfVoters; index++) {
if (voterFavorites[index][1] != -999) {
tallyCard[voterFavorites[index][1]] = tallyCard[voterFavorites[index][1]] + 1;
} else if (voterFavorites[index][2] != -999) {
tallyCard[voterFavorites[index][2]] = tallyCard[voterFavorites[index][2]] + 1;
} else if (voterFavorites[index][3] != -999) {
tallyCard[voterFavorites[index][3]] = tallyCard[voterFavorites[index][3]] + 1;
}
if (voterFavorites[index][4] != -999) {
tallyCard[voterFavorites[index][4]] = tallyCard[voterFavorites[index][4]] - 1;
}
}
}
int determineWinner( int tallyCard[], int maxVotes, int **voterFavorites) {
int x, y, max = 0, min = 999, maxIndex, percent;
for ( x = 0 ; x < 20 ; x++ ) {
if (tallyCard[x] > max) {
maxIndex = x;
max = tallyCard[x];
}
if (tallyCard[x] < min) {
if (tallyCard[x] != -999) {
min = tallyCard[x];
}
}
}
percent = max/maxVotes * 100;
if ( percent >= 50) {
return maxIndex;
} else {
for(x = 0; x < maxVotes ; x++) {
for (y = 0; y < 4; y++) {
if (voterFavorites[x][y] == min) {
voterFavorites[x][y] == -999;
}
}
}
return -444;
}
}
void inputFromFile (void) {
int index, numberOfRestaurants, numberOfVoters, winner;
char *nor, *nov, **restaurantList = malloc(20 * sizeof(char*));;
char **voterNameList = malloc(100 * sizeof(char*));
int **voterFavorites = (int**) calloc(100, sizeof(int*)), tallyCard[20];
int *fav1, *fav2, *fav3, *notFav;
FILE *input;
for ( index = 0; index < 100; index++ ) {
voterFavorites[index] = (int*) calloc(4, sizeof(int));
voterNameList[index] = malloc(26 * sizeof(char));
}
for ( index = 0 ; index < 20; index++ ) {
restaurantList[index] = malloc(51 * sizeof(char));
}
input = fopen ("input_1", "r"); // !!! need to check if this will give an error. Refer to slide set 2-48
if( input == NULL ) {
perror("Error while opening the file.\n");
exit(1);
}
//get names of restaurants
fgets(nor, 51, input);
numberOfRestaurants = atoi(nor); //resolve char * to int
for ( index = 0 ; index < numberOfRestaurants ; index++ ) {
fscanf(input, "%s", restaurantList[index]);
}
//get info lines and names of voters and initial values
fgets(nov, 101, input);
numberOfVoters = atoi(nov); //resolve char * to int
for ( index = 0 ; index < numberOfVoters ; index++ ) {
fscanf(input, "%s %i %i %i %i", voterNameList[index], fav1, fav2, fav3, notFav);
voterFavorites[index][1] = *fav1-1;
voterFavorites[index][2] = *fav2-1;
voterFavorites[index][3] = *fav3-1;
voterFavorites[index][4] = *notFav-1;
}
//count total score for resturants
countScore (voterFavorites, tallyCard, numberOfVoters, numberOfRestaurants);
winner = determineWinner(tallyCard, numberOfVoters, voterFavorites); // !!! probably need to look into these max votes
while (winner < 0) {
countScore(voterFavorites, tallyCard, numberOfVoters, numberOfRestaurants);
winner = determineWinner(tallyCard, numberOfVoters, voterFavorites);
}
outputToFile(winner, restaurantList, voterNameList, numberOfVoters, voterFavorites);
}
int main (void)
{
inputFromFile();
return 0;
}
I've been working on this for a while but I'm sure this could be cleaned up a bit. Sorry about that!

char *nor, *nov, **restaurantList = malloc(20 * sizeof(char*));;
/* ... */
fgets(nor, 51, input);
nor object is not initialized.

Related

Memory leak when changing size of read input

I´m facing really weird issue with my headtail application. When I try to read from file data.txt using Powershell (command: Get-Content data.txt | .\Headtail.exe head 10) I always get proper and expected output. However if I change input from data.txt to fail.txt I won´t get any output from output function (called vypis()).
Does anyone have an idead what is going on here?
GOOD CASE: Output from command (this output is suppose to be same using fail.txt as an input (meaning that content of the given input should be printed)) Get-Content data.txt | .\Headtail.exe head 10 in PowerShell:
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
WRONG CASE: Output from command Get-Content fail.txt | .\Headtail.exe head 10 in PowerShell:
/*NOTHING */
Code for my headtail function is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int const size = 15;
int last_changed = 0;
typedef struct {
char **field;
int *columns;
int rows;
} TMatrix;
void set_size(TMatrix* matrix) {
for (int i = 0; i < matrix->rows; i++) matrix->columns[i] = size;
}
TMatrix* allocate() {
TMatrix* matrix = malloc(sizeof(TMatrix));
if (!matrix) return NULL;
matrix->field = malloc(size * sizeof(char*));
if (!matrix->field) return NULL;
matrix->rows = size;
matrix->columns = malloc(size * sizeof(int));
if (!matrix->field) return NULL;
set_size(matrix);
for (int i = 0; i < matrix->rows; i++) {
matrix->field[i] = malloc(size * sizeof(char));
if (!matrix->field[i]) return NULL;
}
return matrix;
}
void release(TMatrix* matrix) {
for(int i = 0; i < matrix->rows; i++) free(matrix->field[i]);
free(matrix->field);
free(matrix->columns);
free(matrix);
}
bool add_rows(TMatrix* matrix) {
matrix->rows += 10;
char** rebuf = realloc(matrix->field, matrix->rows * sizeof(char*));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field = rebuf;
int* rebufl = realloc(matrix->columns, matrix->rows * sizeof(int));
if (!rebufl) {
free(rebufl);
return false;
}
matrix->columns = rebufl;
for (int i = 1; i <= 10; i++) {
char* rebuh = realloc(matrix->field[matrix->rows - i], size * sizeof(char));
if (!rebuh) {
free(rebuh);
return false;
}
matrix->field[matrix->rows - i] = rebuh;
matrix->columns[matrix->rows - i] = size;
}
return true;
}
bool add_column(TMatrix* matrix, int row) {
matrix->columns[row] += 15;
char* rebuf = realloc(matrix->field[row], matrix->columns[row] * sizeof(char));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field[row] = rebuf;
return true;
}
TMatrix* load(FILE* in) {
char c;
int actual_row = 0, actual_column = 0;
TMatrix* matrix;
if (!(matrix = allocate())) return NULL;
while ((fscanf(in, "%c", &c)) != EOF) {
matrix->field[actual_row][actual_column] = c;
if (c != '\n') {
actual_column += 1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
}
else if (c == '\n') {
actual_column +=1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
matrix->field[actual_row][actual_column] = '\0';
actual_column = 0;
actual_row += 1;
last_changed += 1;
if (((matrix->rows) - 1) == actual_row) {
if (!add_rows(matrix)) return NULL;
}
}
}
return matrix;
}
bool output(FILE* out, TMatrix *matrix, double num_of_output_lines, char method[]) {
if (!matrix) return false;
if (num_of_output_lines <= 0) return false;
if (matrix->rows <= 0) return false;
if (num_of_output_lines > last_changed) return false;
if (strcmp("head", method) == 0) {
for (int i = 0; i < num_of_output_lines; i++) {
for (int j = 0; j < matrix->columns[i]; j++) {
if (matrix->field[i][j] != '\0') fprintf(out, "%c", matrix->field[i][j]);
else break;
}
}
}
else if (strcmp("tail", method) == 0) {
for (int a = (last_changed-1); a >= (last_changed - num_of_output_lines); a--) {
for (int b = 0; b < matrix->columns[a]; b++) {
if (matrix->field[a][b] != '\0') fprintf(out, "%c", matrix->field[a][b]);
else break;
}
}
}
else return false;
return true;
}
void Help() {
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
fprintf(stdout, "* Help function - nothing important *\n");
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
}
int main(int argc, char *argv[])
{
if (argc < 3 || argc > 4) {
printf("!Valid count of arguments entered! \n");
return -1;
}
if (strcmp("-h", argv[1]) == 0) Help();
double num_of_output_lines = atoi(argv[argc - 1]);
TMatrix* matrix = load(stdin);
if (!matrix) {
printf("!Error while loading! \n");
return -1;
}
if (!output(stdout, matrix, num_of_output_lines, argv[argc - 2])) {
printf("!Error while printing! \n");
return -1;
}
release(matrix);
return 0;
}
And content of data.txt (works fine, just an example input):
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.
And finally content of fail.txt (didn´t get any output, the difference is just in length of some rows):
aaaaa.
bbbbbbb.
cccc.
ddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.

Why do I get a segmentation fault accessing a struct?

Edit: added the rest of my code so it's easier to see
I'm receiving a segmentation fault when trying to access certain values of a struct in a header file.
Here's courses.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "structs.h"
void createStudents () {
int random, i;
for (i = 0; i < 12; i++) {
students[i].firstName = firstName[i];
students[i].lastName = lastName[i];
random = 10000 + rand() % 89999;
students[i].num.studentNum = random;
printf("%d - %s, %s \n", students[i].num.studentNum, students[i].lastName, students[i].firstName);
}
}
void createCourses () {
int numbers[999];
int numbersLeft = 999;
char courseCode[512];
char courseCode1[512];
char courseCode2[512];
int numCourses = 3;
int random, i, j;
for (i = 0; i < 999; i++) {
numbers[i] = i;
}
for (j = 0; j < 1; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode, sizeof courseCode, "CS00%d", random);
courses[0].cCode = courseCode;
}
else if (random < 100 && random > 9) {
snprintf(courseCode, sizeof courseCode, "CS0%d", random);
courses[0].cCode = courseCode;
}
else if (random > 99){
snprintf(courseCode, sizeof courseCode, "CS%d", random);
courses[0].cCode = courseCode;
}
courses[0].cName = courseName[0];
courses[0].cDescription = courseDescription[0];
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[0].maxRegister = random;
}
for (j = 0; j < 1; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode1, sizeof courseCode1, "CS00%d", random);
courses[1].cCode = courseCode1;
}
else if (random < 100 && random > 9) {
snprintf(courseCode1, sizeof courseCode1, "CS0%d", random);
courses[1].cCode = courseCode1;
}
else if (random > 99){
snprintf(courseCode1, sizeof courseCode1, "CS%d", random);
courses[1].cCode = courseCode1;
}
courses[1].cName = courseName[1];
courses[1].cDescription = courseDescription[1];
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[1].maxRegister = random;
}
for (j = 0; j < 1; j++) {
random = rand() % numbersLeft;
if (random < 10) {
snprintf(courseCode2, sizeof courseCode2, "CS00%d", random);
courses[2].cCode = courseCode2;
}
else if (random < 100 && random > 9) {
snprintf(courseCode2, sizeof courseCode2, "CS0%d", random);
courses[2].cCode = courseCode2;
}
else if (random > 99){
snprintf(courseCode2, sizeof courseCode2, "CS%d", random);
courses[2].cCode = courseCode2;
}
courses[2].cName = courseName[2];
courses[2].cDescription = courseDescription[2];
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
random = 4 + rand() % 4;
courses[2].maxRegister = random;
}
}
void regiserStudents () {
int checkSum = 0, checkSum1 = 0, checkTemp = 0, count0 = 0, count1 = 0, count2 = 0;
int wCount0 = 0, wCount1 = 0, wCount2 = 0;
int v, i, j, random, max0, max1, max2;
max0 = courses[0].maxRegister;
max1 = courses[1].maxRegister;
max2 = courses[2].maxRegister;
for (i = 0; i < 2; i++) {
checkTemp = count0;
for (j = 0; j < 12; j++) {
random = rand() % 3;
if (random == 0) {
if (count0 == 0) {
courses[random].registered[count0] = &students[j];
count0++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[0].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else if (count0 == max0) {
courses[random].waitlisted[count0] = &students[j];
wCount0++;
}
else {
courses[random].registered[count0] = &students[j];
count0++;
}
/*}*/
}
}
}
if (random == 1) {
if (count1 == 0) {
courses[random].registered[count1] = &students[j];
count1++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[1].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else if (count1 == max1) {
courses[random].waitlisted[count1] = &students[j];
wCount1++;
}
else {
courses[random].registered[count1] = &students[j];
count1++;
}
}
}
}
if (random == 2) {
if (count2 == 0) {
courses[random].registered[count2] = &students[j];
count2++;
}
else {
checkSum1 = students[j].num.studentNum;
for (v = 0; v < checkTemp; v++) {
checkSum = courses[2].registered[v]->num.studentNum;
if (checkSum == checkSum1) {
/*Do Nothing*/
}
else if (count2 == max2) {
courses[random].waitlisted[count2] = &students[j];
wCount2++;
}
else {
courses[random].registered[count2] = &students[j];
count2++;
}
}
}
}
}
}
courses[0].studentRegistered = count0;
courses[1].studentRegistered = count1;
courses[2].studentRegistered = count2;
courses[0].studentWaitlisted = wCount0;
courses[1].studentWaitlisted = wCount1;
courses[2].studentWaitlisted = wCount2;
}
void printCourses () {
int i;
printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[0].cCode, courses[0].cName, courses[0].cDescription, courses[0].studentRegistered, courses[0].maxRegister);
for (i = 0; i < courses[0].studentRegistered; i++) {
printf("* %d - %s, %s \n", courses[0].registered[i]->num.studentNum, courses[0].registered[i]->lastName, courses[0].registered[i]->firstName);
}
printf("Waitlisted Students (%d)", courses[0].studentWaitlisted);
if (courses[0].studentWaitlisted == 0) {
printf("\n");
}
else {
for (i = 0; i < courses[0].studentWaitlisted; i++) {
printf("* %d - %s, %s \n", courses[0].waitlisted[i]->num.studentNum, courses[0].waitlisted[i]->lastName, courses[0].waitlisted[i]->firstName);
}
}
printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[1].cCode, courses[1].cName, courses[1].cDescription, courses[1].studentRegistered, courses[1].maxRegister);
for (i = 0; i < courses[1].studentRegistered; i++) {
printf("* %d - %s, %s \n", courses[1].registered[i]->num.studentNum, courses[1].registered[i]->lastName, courses[1].registered[i]->firstName);
}
printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[2].cCode, courses[2].cName, courses[2].cDescription, courses[2].studentRegistered, courses[2].maxRegister);
for (i = 0; i < courses[2].studentRegistered; i++) {
printf("* %d - %s, %s \n", courses[2].registered[i]->num.studentNum, courses[2].registered[i]->lastName, courses[2].registered[i]->firstName);
}
}
And here's my header file
structs.h
#ifndef STRUCTS_H_
#define STRUCTS_H_
char *firstName[] = {
"Emma", "Liam", "Olivia",
"Noah", "Ava", "Logan",
"Sophia", "Lucas", "Isabella",
"Mason", "Shaylyn", "Jack"
};
char *lastName[] = {
"Smith", "Johnson", "Williams",
"Brown", "Jones", "Miller",
"Davis", "Garcia", "Rodriguez",
"Wilson", "Seguin", "Loveday"
};
typedef struct{
int studentNum;
}studentNumber;
typedef struct{
char *firstName;
char *lastName;
studentNumber num;
}studentID;
studentID students[12];
char *courseName[] = {"Web Programming", "Technical Communication", "Processor Architecture"};
char *courseDescription[] = {"Learn the language of HTML, and how to create websites.", "Learn the essentials of communication skills, and how to apply them on the job.", "Learn the basics of circuits and Machine Language coding."};
typedef struct {
int maxRegister;
char *cCode;
char *cName;
char *cDescription;
studentID *registered[8];
studentID *waitlisted[12];
int studentRegistered;
int studentWaitlisted;
}course;
course courses[3];
#endif
Printing the values of the registered students works fine, but when I print the waitlisted students I get a segmentation error. I used gdb and found it was on this line but couldn't figure out why:
printf("%d - %s, %s \n", courses[0].waitlisted[i]->num.studentNum, courses[0].waitlisted[i]->lastName, courses[0].waitlisted[i]->firstName);
studentID *waitlisted[12]; That means they will hold the address of variable of type structure studentID. You simply didn't do this but start to access those pointer variables. You have passed them to scanf which invokes undefined behavior due to trying to read an unintialized pointer variable.
So what you need to do here -
courses[i].waitlisted = malloc(sizeof *courses[i].waitlisted * courses[i].studentWaitlisted);
Same goes for the studentID also. Here fistName is a char* you need to allocate some meory to access it otherwise it's UB.
Or
typedef struct{
char firstName[100]; //you are considering that name length would be 100
//at max.
char lastName[100];
studentNumber num;
}studentID;
After OP edited question:
The seg fault you get is because of accessing a local variable after it's lifetime ended.
courses[0].cCode = courseCode;
What you can do is
courses[0].cCode = strdup(courseCode);
Initialize array int numbers[999]={0}; otherwise you might access garbage value as the indexing is result of random number geneartion.
if( random < 999){
numbers[random] = numbers[numbersLeft-1];
numbersLeft--;
}
else{
fprintf(stderr, "%s\n","Error" );
}
Lots of repeated code. You should remove repeated code. And also there is no need for single-iteration-for-loop.

Possible mode error

I've made this program that computes the mean, the median and the mode from an array. Although I've tested with some examples, I found out there might be a case that I have forgotten as for many of the inputs I've tested it works but the testing program that my teacher is using gave me an error for a certain test, but I was not presented with its input. Maybe someone can have a look and see if I am making a mistake at the mode point of the code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
scanf("%d", &n);
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
int value;
scanf("%d", &value);
array[i] = value;
}
//mean
double mean;
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
mean = sum / n;
printf("mean: %.2f\n", mean);
//median
float temp;
int j;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1, possibleMax = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
}
if (array[i] != val) {
val = array[i];
noOfRepetitions = 1;
}
if (noOfRepetitions == possibleMax) {
maxRepetitions = 1;
continue;
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
possibleMax = maxRepetitions;
}
}
if (maxRepetitions > 1) {
printf("mode: %d\n", valMax);
} else {
printf("mode: NONE\n");
}
return 0;
}
My idea for mode was because the numbers are sorted when just transverse it. If the next element is the same as the previous one, increase the noOfRepetitions. If the noOfRepetition is bigger than the maxRepetitions until now, replace with that. Also store the last maximum val needed if we have for example more than 2 numbers with the same number of repetitions.
EDIT: The mode of an array should return the number with the maximum number of occurrences in the array.If we have 2 or more number with the same number of maximum occurrences , there isn't a mode on that array.
I've discovered my mistake. I didn't think of the case when I have numbers with same maximum frequency and after that came one with lower frequency but still bigger than others. For example : 1 1 1 2 2 2 3 3 4 5 6.With my code , the result would have been 3 . I just needed to change the comparison of noOfRepetitions with oldMaxRepetition.
There seems to be no purpose for the variable possibleMax. You should just remove these lines:
if(noOfRepetitions==possibleMax){
maxRepetitions=1;
continue;
}
They cause maxRepetitions to be reset erroneously.
You could detect if the distribution is multimodal and print all mode values:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
if (scanf("%d", &array[i]) != 1)
return 1;
}
//mean
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
printf("mean: %.2f\n", sum / n);
//median
int j;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
} else {
val = array[i];
noOfRepetitions = 1;
}
}
if (maxRepetitions == 1) {
printf("mode: NONE\n");
} else {
printf("mode: %d", valMax);
val = array[0];
noOfRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
} else {
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
printf("\n");
}
return 0;
}
Your code to search a mode seems too complicated. Compare this:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
if (++noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
}
else
{
val = array[i];
noOfRepetitions = 1;
}
}
It's probably the simplest code to do what you need, but it overwrites maxVal and maxRepetitions much too often.
The following version overwrites the two 'max' variables only once per each new maximum found – at the cost of duplicating some part of code:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
++noOfRepetitions;
}
else
{
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}

Read each files on file_list array, and search max_value in rows on each files in C

I have the filelist array without extension(which is like 2, 5, 8, 11, etc..), and try to read it as a text file(2.txt, 5.txt, 8.txt, 11.txt).
And each files have 3 rows, and 513 columns, which is like..
wavenumber wavelength PS
0.000000e+00 inf 1.339797e+10
2.667793e-04 2.355200e+04 2.264711e+07
5.335585e-04 1.177600e+04 5.774260e+06
8.003378e-04 7.850667e+03 4.347408e+06
1.067117e-03 5.888000e+03 2.071735e+06
1.333896e-03 4.710400e+03 1.338209e+06
1.600676e-03 3.925333e+03 1.010330e+06
1.867455e-03 3.364572e+03 7.951162e+05
2.134234e-03 2.944000e+03 6.293471e+05
2.401013e-03 2.616889e+03 5.702861e+05
2.667793e-03 2.355200e+03 4.124521e+05
2.934572e-03 2.141091e+03 3.946834e+05
3.201351e-03 1.962667e+03 4.367024e+05
3.468130e-03 1.811692e+03 4.606193e+05
3.734910e-03 1.682286e+03 3.691915e+05
4.001689e-03 1.570133e+03 4.260768e+05
4.268468e-03 1.472000e+03 5.516758e+05
4.535248e-03 1.385412e+03 9.301200e+05
4.802027e-03 1.308444e+03 1.307440e+06
5.068806e-03 1.239579e+03 1.739384e+06
5.335585e-03 1.177600e+03 3.961967e+06
5.602365e-03 1.121524e+03 9.018276e+06
5.869144e-03 1.070545e+03 1.564086e+07
6.135923e-03 1.024000e+03 6.533970e+07
6.402702e-03 9.813333e+02 1.299191e+07
6.669482e-03 9.420800e+02 6.127578e+06
6.936261e-03 9.058461e+02 2.723106e+06
7.203040e-03 8.722963e+02 1.135096e+06
7.469819e-03 8.411429e+02 5.839772e+05
7.736599e-03 8.121379e+02 5.686039e+05
8.003378e-03 7.850667e+02 4.622423e+05
8.270157e-03 7.597419e+02 6.013722e+05
8.536937e-03 7.360000e+02 5.963052e+05
8.803716e-03 7.136970e+02 7.575063e+05
9.070495e-03 6.927059e+02 9.150109e+05
9.337274e-03 6.729143e+02 8.281556e+05
9.604054e-03 6.542222e+02 1.441827e+06
9.870833e-03 6.365405e+02 2.293378e+06
1.013761e-02 6.197895e+02 4.720661e+06
1.040439e-02 6.038975e+02 9.183591e+06
1.067117e-02 5.888000e+02 1.244082e+07
1.093795e-02 5.744390e+02 2.475937e+07
1.120473e-02 5.607619e+02 3.096345e+07
1.147151e-02 5.477209e+02 5.709620e+07
1.173829e-02 5.352727e+02 1.128015e+08
1.200507e-02 5.233778e+02 1.951984e+08
1.227185e-02 5.120000e+02 3.567358e+08
1.253863e-02 5.011064e+02 1.038480e+08
1.280540e-02 4.906667e+02 6.609837e+07
1.307218e-02 4.806531e+02 3.366062e+07
1.333896e-02 4.710400e+02 3.214113e+07
1.360574e-02 4.618039e+02 1.068869e+07
1.387252e-02 4.529231e+02 6.818056e+06
1.413930e-02 4.443773e+02 4.110327e+06
1.440608e-02 4.361482e+02 3.497202e+06
1.467286e-02 4.282182e+02 2.220670e+06
1.493964e-02 4.205714e+02 1.557209e+06
1.520642e-02 4.131930e+02 1.305517e+06
1.547320e-02 4.060690e+02 1.336280e+06
1.573998e-02 3.991864e+02 1.055823e+06
1.600676e-02 3.925333e+02 1.249962e+06
1.627354e-02 3.860984e+02 2.264681e+06
1.654031e-02 3.798710e+02 3.177218e+06
1.680709e-02 3.738413e+02 4.535130e+06
1.707387e-02 3.680000e+02 3.768252e+06
1.734065e-02 3.623385e+02 9.292287e+06
1.760743e-02 3.568485e+02 1.537548e+07
1.787421e-02 3.515224e+02 1.766043e+07
1.814099e-02 3.463529e+02 1.719145e+07
1.840777e-02 3.413333e+02 3.127401e+07
1.867455e-02 3.364572e+02 1.841132e+07
1.894133e-02 3.317183e+02 1.283891e+07
1.920811e-02 3.271111e+02 8.802511e+06
1.947489e-02 3.226301e+02 6.138252e+06
1.974167e-02 3.182703e+02 3.253741e+06
2.000845e-02 3.140267e+02 2.274736e+06
2.027522e-02 3.098947e+02 1.761115e+06
2.054200e-02 3.058701e+02 1.719121e+06
2.080878e-02 3.019487e+02 2.010613e+06
2.107556e-02 2.981266e+02 1.804399e+06
2.134234e-02 2.944000e+02 2.074000e+06
2.160912e-02 2.907654e+02 1.910002e+06
2.187590e-02 2.872195e+02 2.917329e+06
2.214268e-02 2.837590e+02 3.900309e+06
2.240946e-02 2.803810e+02 4.747046e+06
2.267624e-02 2.770824e+02 8.309638e+06
2.294302e-02 2.738605e+02 9.704105e+06
2.320980e-02 2.707126e+02 1.337196e+07
2.347658e-02 2.676364e+02 1.850881e+07
2.374335e-02 2.646292e+02 2.134344e+07
2.401013e-02 2.616889e+02 2.865988e+07
2.427691e-02 2.588132e+02 2.796588e+07
2.454369e-02 2.560000e+02 3.577728e+07
2.481047e-02 2.532473e+02 2.592449e+07
2.507725e-02 2.505532e+02 2.117858e+07
2.534403e-02 2.479158e+02 1.466834e+07
2.561081e-02 2.453333e+02 1.447010e+07
2.587759e-02 2.428041e+02 8.931647e+06
2.614437e-02 2.403265e+02 5.346297e+06
2.641115e-02 2.378990e+02 3.370142e+06
2.667793e-02 2.355200e+02 2.844172e+06
2.694471e-02 2.331881e+02 2.385213e+06
2.721149e-02 2.309020e+02 2.559934e+06
2.747826e-02 2.286602e+02 2.235514e+06
2.774504e-02 2.264615e+02 2.389616e+06
2.801182e-02 2.243048e+02 2.091203e+06
2.827860e-02 2.221887e+02 3.688845e+06
2.854538e-02 2.201122e+02 4.157106e+06
2.881216e-02 2.180741e+02 4.784280e+06
2.907894e-02 2.160734e+02 6.942617e+06
2.934572e-02 2.141091e+02 8.618190e+06
2.961250e-02 2.121802e+02 9.034358e+06
2.987928e-02 2.102857e+02 1.041257e+07
3.014606e-02 2.084248e+02 1.210773e+07
3.041284e-02 2.065965e+02 1.181222e+07
3.067962e-02 2.048000e+02 1.478849e+07
3.094640e-02 2.030345e+02 1.399273e+07
And so on...
So I made a 2d array, and tried to findout the MAX values of each column.
/*openfiles according to reprogramed filelist*/
for(i =2; i<file_count; i++) {
strcat(filelist[i],".txt");
if((fp = fopen( filelist[i], "r")) == NULL)
{
perror("error to openfiles");
exit(1);
}
/*declare the variables*/
char data[3][513];
//char wavenumber[513], wavelength[513], powerspec[513];
int COL, ROW, MAX_wavenumber, MAX_wavelength, MAX_powerspec;
int HEIGHT,WIDTH;
HEIGHT = 513;
WIDTH = 3;
//input data to new array
for(COL = 0; COL < HEIGHT; COL++) {
for (ROW = 0; ROW < WIDTH; ROW++) {
fscanf(fp, "%s", &data[ROW][COL]);
}
}
//start of comparison of data
for(COL = 2; COL < HEIGHT - 1; COL++) { //number starts from the 3rd column
while(ROW == 1) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavenumber = atof(&data[ROW][COL+1]);
}
while(ROW == 2) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavelength = atof(&data[ROW][COL+1]);
}
}
while(ROW == 3)
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_powerspec = atof(&data[ROW][COL+1]);
}
}
}
printf("MAX_wavenumber : %d",MAX_wavenumber);
printf("MAX_wavelength : %d",MAX_wavelength);
printf("MAX_powerspec : %d",MAX_powerspec);
fclose(fp);
}
This does not start at all !!
Here's my full code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
char *remove_ext (char* mystr, char dot, char sep);
int main()
{
char fname1[256],fname2[256];
char folderpath[256];
int mod;
int re_mainder;
char *tem;
char filenameNoExtension;
char **filelist;
int i,j,l;
char ***ls = &filelist;
int file_count = 0;
char *s;
DIR* dp = NULL;
struct dirent* entry = NULL;
FILE* fp = NULL;
/*open folder*/
printf("enter the folder path : ");
scanf("%s",folderpath);
/* Err message of opening directory */
if((dp = opendir(folderpath)) ==NULL) {
fprintf(stderr,"unidentified folder : %s",folderpath);
return 0;
}
*ls = NULL;
/*file count*/
while ((entry = readdir(dp)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
++file_count;
}
/* rewind the directory and need to reallocate memory for reading 18250 files */
rewinddir(dp);
*ls = calloc(file_count, sizeof(char*));
/*make the array of filelist*/
file_count = 0;
entry = readdir(dp);
while(NULL != entry) {
(*ls)[file_count++] = strdup(entry->d_name);
entry = readdir(dp);
}
/*remove the extension */
for(i = 0; i < file_count; i++) {
filelist[i] = remove_ext(filelist[i], '.', '/');
}
closedir(dp);
//loop starts at 2 for get rid of space & .
for(i = 2; i< file_count; i++) {
printf("%s\n",filelist[i]);
}
/*select the mod & remainder*/
printf("select the mod number : ");
scanf("%d", &mod);
printf("select the remainder : ");
scanf("%d",&re_mainder);
/*sort files by the remainder*/
for(i = 2; i<file_count; i++) {
if( atoi( filelist[i] )%mod == re_mainder) { /*use atoi function for changing string to int*/
filelist[i] = filelist[i];
}
else
filelist[i] = "delete";
}
//delete the "delete" in array
l = file_count;
for(i = 0; i<l; i++) {
if (strcmp(filelist[i], "delete") == 0 ) {
for(j = i; j < l; j++)
filelist[j]=filelist[j+1];
i--; //check again from same index i
l--; //Decreasing the length of the array
}
}
/* resize the modified file_count */
file_count = sizeof(filelist)/sizeof(filelist[0]);
for(i =2; i<file_count; i++) {
printf("%s\n",filelist[i]);
}
/********** **HERE"S MY QUESTION** **********/
/**********openfiles according to reprogramed filelist**********/
for(i =2; i<file_count; i++) {
strcat(filelist[i],".txt");
if((fp = fopen( filelist[i], "r")) == NULL)
{
perror("error to openfiles");
exit(1);
}
/*declare the variables*/
char data[3][513];
//char wavenumber[513], wavelength[513], powerspec[513];
int COL, ROW, MAX_wavenumber, MAX_wavelength, MAX_powerspec;
int HEIGHT,WIDTH;
HEIGHT = 513;
WIDTH = 3;
//input data to new array
for(COL = 0; COL < HEIGHT; COL++) {
for (ROW = 0; ROW < WIDTH; ROW++) {
fscanf(fp, "%s", &data[ROW][COL]);
}
}
//start of comparison of data
for(COL = 2; COL < HEIGHT - 1; COL++) { //number starts from the 3rd column
while(ROW == 1) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavenumber = atof(&data[ROW][COL+1]);
}
while(ROW == 2) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavelength = atof(&data[ROW][COL+1]);
}
}
while(ROW == 3)
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_powerspec = atof(&data[ROW][COL+1]);
}
}
}
printf("MAX_wavenumber : %d",MAX_wavenumber);
printf("MAX_wavelength : %d",MAX_wavelength);
printf("MAX_powerspec : %d",MAX_powerspec);
fclose(fp);
}
}
//this is just for removing the extension of files
char *remove_ext (char* mystr, char dot, char sep) {
char *retstr, *lastdot, *lastsep;
// Error checks and allocate string.
if (mystr == NULL)
return NULL;
if ((retstr = malloc (strlen (mystr) + 1)) == NULL)
return NULL;
// Make a copy and find the relevant characters.
strcpy (retstr, mystr);
lastdot = strrchr (retstr, dot);
lastsep = (sep == 0) ? NULL : strrchr (retstr, sep);
// If it has an extension separator.
if (lastdot != NULL) {
// and it's before the extenstion separator.
if (lastsep != NULL) {
if (lastsep < lastdot) {
// then remove it.
*lastdot = '\0';
}
} else {
// Has extension separator with no path separator.
*lastdot = '\0';
}
}
// Return the modified string.
return retstr;
}

Double free/corruption?

typedef struct {
int *info;
} row;
struct {
row* head;
int len;
int size;
} list;
int main{
list.len = 0;
list.size = 1;
list.head = malloc(list.size * sizeof(row));
//...... some other code that calls addRow (list.len) times
for (i = list.len - 1; i > 0; i--) {
free(list.head[i].info);/*****HERE**********/
}
free(list.head);
}
void addRow(int* data) {
int i;
if (list.len == list.size) {
row *temp = malloc(sizeof(row) * list.size * 2);
if (temp == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < list.len; i++) {
temp[i] = list.head[i];
}
free(list.head);
list.head = temp;
}
list.head[list.len].info = malloc(sizeof(int) * numCols);
for (i = 0; i < numCols; i++) {
list.head[list.len].info[i] = data[i];
}
list.len++;
}
This is the code that I used to addRow is were I malloc all the data. and I don't see why I'm getting a double free/ corruption error. At the area I marked HERE, I believe I am malloc-ing for all instances of info in the row struct, These line are the only ones doing malloc/free.
I just want to get into the habit free-ing properly when terminating the program.
FULL PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct {
int *info;
} row;
struct {
row* head;
int len;
int size;
} list;
static int sortCol, numCols;
int qSortCompare(const void*, const void*);
void printList();
int processInput();
void nullify(char*, int);
int main(int n, char **args) {
sortCol = 1;
numCols = 0;
if (n > 1 && args[1][0] == '-' && args[1][1] == 'c') {
sortCol = atoi(args[2]);
}
list.len = 0;
list.size = 1;
list.head = malloc(list.size * sizeof(row));
processInput();
if (sortCol < 1 || sortCol > numCols) {
fprintf(stderr, "Error (enter): (Line ##) Invalid column to sort.\n");
return 1;
}
printList();
qsort(list.head, list.len, sizeof(row), &qSortCompare);
printf("\n");
printList();
int i;
printf("add1:%p\nadd2:%p\n", list.head[0].info, list.head[1].info);
for (i = 0; i < list.len; i++) {
free(list.head[i].info);
}
free(list.head);
return 0;
}
void nullify(char* str, int n) {
int i;
for (i = 0; i < n; i++)
str[i] = '\0';
}
int parseInt(char *str, int index) {
int num = -1;
sscanf(str + index, "%d", &num);
return num;
}
void addRow(int* data) {
int i;
if (list.len == list.size) {
row *temp = malloc(sizeof(row) * list.size * 2);
if (temp == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < list.len; i++) {
temp[i] = list.head[i];
}
free(list.head);
list.head = temp;
}
list.head[list.len].info = malloc(sizeof(int) * numCols);
if (list.head[list.len].info == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < numCols; i++) {
list.head[list.len].info[i] = data[i];
}
list.len++;
}
int processInput() {
int i, maxChars = 200, totalN = 0;
int *nums, curNumIndex = 0, onNum, curNum;
numCols = maxChars / 2;
nums = (int*) (malloc(sizeof(int) * numCols));
char str[maxChars], ch;
for (i = 0; i < numCols; i++) {
nums[i] = -1;
}
while (!feof(stdin)) {
nullify(str, maxChars);
fgets(str, maxChars, stdin);
onNum = isdigit(str[0]);
curNumIndex = 0;
for (i = 0; i < maxChars; i++) {
ch = str[i];
if ((!isspace(ch)) && (!isdigit(ch)) && (ch != '\0')) {
fprintf(stderr, "Error 1: (Line ##) Invalid char in input.\n");
//return 0;
}
if (isspace(ch) && onNum) {
curNum = parseInt(str, curNumIndex);
curNumIndex = i;
nums[totalN % numCols] = curNum;
totalN++;
if (totalN % numCols == 0)
addRow(nums);
} else {
onNum = isdigit(str[i]);
}
if (ch == '\n' || ch == '\0')
break;
}
if (numCols > totalN) {
if (totalN > 0) {
numCols = totalN;
addRow(nums);
} else {
fprintf(stderr,
"Error (enter): (Line ##) Invalid first line of input.\n");
}
}
if (ch != '\n' && ch != '\0') {
fprintf(stderr,
"Error (enter): (Line ##) A row from input too long.\n");
//return 0;
}
}
return 1;
}
int qSortCompare(const void *c1, const void *c2) {
row *t1, *t2;
t1 = (row*)c1;
t2 = (row*)c2;
return t1->info[sortCol - 1] - t2->info[sortCol - 1];
}
void printList() {
int i, j;
for (i = 0; i < list.len; i++) {
for (j = 0; j < numCols; j++) {
printf("%10d ", list.head[i].info[j]);
}
printf("\n");
}
}
Program needs a EOF terminated input of integer numbers. Specifically with the same number of integers before the newline.
UPDATE: I used gdb to analysis the free part i it only fails on the second iteration, using for(i = 0; i < list.len; i++) and for(i = list.len - 1; i > 0 ; i--)
Another thing is that I don't see the update to list.size (it should be updated when resizing head)
"I just want to get into the habit free-ing properly when terminating the program."
The correct way to handle things like this is to free a non-NULL pointer and then set the pointer to NULL.
For example:
int* x = malloc (sizeof (int));
if (x != NULL) {
free (x);
x = NULL;
}
/* Misc. Code ... */
/* Now for whatever reason, you want to free x again */
/* This branch is never triggered, because you were smart enough to set x to NULL
* when you freed it the first time...
*/
if (x != NULL) {
free (x);
x = NULL;
}

Resources