C++ - incrementing integer variable does not work

So I'm creating a program that implements several classes representing a school, and its students and courses. I'm running into an issue in School.cc where the addTaken() finds the student object with the given student number and the course object with the given course code, and then creates a new Taken object with the found student and course objects and adds it to the back of the Taken collection which is studentCoursePairs[].

The problem is the variable numTaken never increments despite having the '++'. It seems to always stay at 0. If numTaken is 0, the loop immediately stops (as 0 < 0 is false) and numTaken is never incremented for this reason. I was wondering if anyone knows how to fix this?

Since numTaken is always 0 it won't let me print anything in the Taken collection out.

School.cc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <iomanip>
using namespace std;
#include <string.h> 

#include "School.h"

School::School(string s1) : name(s1){ 
    numTaken = 0;
}

void School::addTaken(string number, int code, string grade){
    Student* s = nullptr;
    Course* c = nullptr;
    if((studentsCollection->find(number, &s)) && (coursesCollection->find(code, &c))){
        Taken* taken = new Taken(s, c, grade);
        studentCoursePairs[numTaken] = taken;            
        ++numTaken;
    }
}

void School::printTaken(){
    cout << name << " === TAKEN: "<< endl;
    for(int i = 0; i < numTaken; ++i){
        studentCoursePairs[i]->print(); //seg fault
    }   
}


Last edited on
In addTaken(), why the for loop?
despite having the '++'

Only if it ever runs that section.

I should stop using pointers with explicit dynamic allocation (which is going to lead to memory leak sooner or later) and just use vectors.
Last edited on
Sorry, I accidentally copied an old version that caused a seg fault. I updated it to remove the for loop - so now the seg fault is gone but numTaken just doesn't increment for some reason. I think it's because of the fact that find() in the other two classes is a boolean function and stops running when it returns but I don't know how to get around this.

When I print numTaken in the School's print function, it's always 0 no matter where I increment it in addTaken(). And because it stays at 0, nothing ever prints.
Last edited on
You do not use numTaken anywhere. The print function should look like:
1
2
3
4
5
6
void School::printTaken(){
    cout << name << " === TAKEN: "<< endl;
    for(int i = 0; i < numTaken; ++i){ // Note: numTaken instead of sizeof...
        studentCoursePairs[i]->print(); //it shouldn't seg fault unless numTaken > MAX_STUDENTS
    }   
}
Last edited on
What type is studentCoursePairs? Shouldn't the loop be dependent upon numTaken?

1
2
3
4
5
6
void School::printTaken(){
    cout << name << " === TAKEN: "<< endl;
    for(int i = 0; i < sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0]); ++i){
        studentCoursePairs[i]->print(); //seg fault
    }   
}


Consider:

1
2
3
4
5
6
void School::printTaken(){
    cout << name << " === TAKEN: "<< endl;
    for(int i = 0; i < numTaken; ++i){
        studentCoursePairs[i]->print();
    }   
}


If
Last edited on
Fixed! Unfortunately still dealing with the issue that numTaken is always 0 :(
studentCoursePairs is a Taken object. Each Taken object represents the fact that a specific student has taken a specific course, and it will store the grade that the student earned in that course.

Even if I added 'numTaken' in the for loop instead, if I add a print statement above the for loop that prints out the value of numTaken it's 0 for some reason. It never gets incremented in addTaken(). I was told my find functions in StudentCollection and CourseCollection always return on the first iteration of the loop which is probably why but I don't know how to get past this as both my find functions must be boolean.
Last edited on
In studentCollection, when is size incremented? In coursesCollection, when is numCourses incremented? In the .find(), are these numbers as expected?

Is the data in studentCollection and coursesCollection OK - verified with a print?

What debugging of this code have you done? The debugger should be your best friend when trying to find out what's happening and why it's not working as expected.

I updated the code to include the add function in StudentCollection. There's also an add function in CoursesCollection which is basically the exact same thing but checks for the course code instead of student number. Size is incremented in the add function in these classes.

All add() does in these functions is add the Student/Course object to their collection in ascending order by their alphabetical name/course code. There are different print functions to print all students in the school and all courses in the school.

The size integer in these functions are unrelated to numTaken. I'm worried about getting numTaken to increment for when I print courses taken by a specific student.
Last edited on
In StudentCollection is size changed? Or in CoursesCollection numCourses?

numTaken is only taken/incremented when both find functions return true.
size is incremented in the add function in StudentCollection. This number basically represents the number of total Student objects in the school. CoursesCollection also has a variable size and an identical add function that represents the total number of different courses offered at the school.

numTaken is separate and only belongs to the School class. It represents the total number of courses taken by a specific student. So basically the number of Taken objects in the array which is determined by addTaken()
Last edited on
numTaken is separate and only belongs to the School class. It represents the total number of courses taken by a specific student. So basically the number of Taken objects in the array which is determined by addTaken()
Yes, but due to this line:

if((studentsCollection->find(number, &s)) && (coursesCollection->find(code, &c))){

numTaken depends on StudentCollection and CoursesCollection. So you need to check whether their data is correctly set.
@OP FWIW, I reckon you data model and naming could do with a 're-spray' along the following lines. I see you ignored <vector>'s for C-style arrays - a teaching constraint maybe? <maps> would be even better ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>

class Student
{
public:
    std::string name;
    int ID;
    Student(){};
    Student( std::string n, int id){ name = n; ID = id; }
};

class Course
{
public:
    std::string name;
    int course_no;
    Course(){};
    Course( std::string n, int c){ name = n; course_no = c; }
};

class Enrolment
{
public:
    Student student;
    Course course;
    int grade{0};
    Enrolment(){};
    Enrolment(Student s, Course c){ student = s; course = c; }
};

class School
{
public:
    std::string name;
    
    int no_students{0};
    int no_courses{0};
    int no_enrolments{0};
    
    Student* roll = new Student[5];
    Course* curriculum = new Course[20];
    Enrolment* report = new Enrolment[100];
    
    void addStudent(Student s){roll[no_students] = s; no_students++;}
    void addCourse(Course c){curriculum[no_courses] = c; no_courses++;}
    void addEnrolment(Enrolment e){report[no_enrolments] = e; no_enrolments++;}
    
    void display_students()
    {
        for(int i = 0; i < no_students; i++)
        std::cout << roll[i].ID << '\t' << roll[i].name << '\n';
    }
    
    void display_courses()
    {
        for(int i = 0; i < no_courses; i++)
        std::cout << curriculum[i].course_no << '\t' << curriculum[i].name << '\n';
    }
    
    void display_enrolments()
    {
        for(int i = 0; i < no_enrolments; i++)
        std::cout
        << i << '\t' << report[i].student.name << " -> "
        << report[i].course.name << '\t' << "Grade: " << report[i].grade << '\n';
    }
    
    void setGrade(int i, int g)
    {
        report[i].grade = g;
    }
};

int main()
{
    School eton; eton.name = "Eton";
    
    Student s1("Mary",11), s2("Bob",22), s3("Jack",44);
    eton.addStudent(s1); eton.addStudent(s2);  eton.addStudent(s3);
    eton.display_students();
    
    Course c1("Woodwork", 23); Course c2("English", 541);
    eton.addCourse(c1); eton.addCourse(c2);
    eton.display_courses();
    
    Enrolment e1(s1,c2), e2(s1,c1), e3(s2,c2), e4(s3,c2);
    eton.addEnrolment(e1); eton.addEnrolment(e2); eton.addEnrolment(e3); eton.addEnrolment(e4);
    eton.display_enrolments();
    
    eton.setGrade(1,96);
    eton.setGrade(2,87);
    eton.display_enrolments();
    
    return 0;
}


11	Mary
22	Bob
44	Jack
23	Woodwork
541	English
0	Mary -> English	Grade: 0
1	Mary -> Woodwork	Grade: 0
2	Bob -> English	Grade: 0
3	Jack -> English	Grade: 0
0	Mary -> English	Grade: 0
1	Mary -> Woodwork	Grade: 96
2	Bob -> English	Grade: 87
3	Jack -> English	Grade: 0
Program ended with exit code: 0
Topic archived. No new replies allowed.