Search code examples
c++classpointersgarbage

c++ classes and garbage data


For my last project this year I am trying to make a Gradebook program in C++. Using classes vs structs, new and delete instead of malloc and free, I am to recreate my previous homework written in C. In my last question someone told me to stop making my variables private as I have a pointer to that class from my main Class.

in gradebook.h

class Student {
 public: 
  string last;
  string first;
  int student_id;
  int count_student;
};

class Course {
 public:
   string name;
   int course_id;
   int count_course;

};

class Gradebook {
 public:
  Gradebook();
  void addCourse();
  void addStudent();
  void printCourse();
  void printStudent();

 private:
  Course *courses;
  Student *students;
 };

in gradebook.cpp

 Gradebook::Gradebook() {

  courses = new Course;
  courses->count_course=0;
  courses->course_id = 0;


  students = new Student;
  students->count_student=0;
  students->student_id=0;    

}

Gradebook::addCourse() {

 int i, loop=0;

 cout << "Enter number of Courses: ";
 cin >> loop;

 for(i=0; i<loop; i++) {

  cout << "Enter Course ID: ";
  cin >> courses[courses->count_courses].course_id;

  cout << "Enter Course Name: ";
  cin >> courses[courses->count_courses].name;

  courses->count_course++;

 }

}

 Gradebook::addStudent() {

   //same information from addCourse but goes to students variables

 }

Gradebook::printCourse() {

 int i;

 for(i=0; i<courses->count_course; i++) {

   cout << courses[i].course_id << "\t\t";
   cout << courses[i].name << endl;

 }

}

Gradebook::printStudent() {

 int i;

 for(i=0; i<students->count_student; i++) {

   cout << students[i].student_id << "\t\t";
   cout << students[i].last << "\t\t";
   cout << students[i].first << endl;

 }

}

When I run addCourse function then run printCourse it works.

Then I run addStudent function then run printStudent it works.

Problem:

After I add students and rerun printCourse I get garbage data when courses[i].course_id gets printed. But only when i=2. courses[i=2].name still prints with the correct data. I can add more courses and add more students and they print out just fine, again only when i=2 does course_id get garbage data. I've been stuck for a few days and I tried to look at it a different way until @wheaties mentioned that what I was doing previously was correct and it should be public. So can one of you guys help me out?


Solution

  • Problem:

    in Gradebook::Gradebook(), you construct a single Course:

    courses = new Course;
    courses->count_course=0;
    courses->course_id = 0;
    

    and the same goes for Student. You need to construct either an array or use one of the STL's containers. For this case, I'd recommend either std::list or std::deque. A simple usage would be:

    class Gradebook {
      std::list<Course> courses;
    }
    
    void Gradebook::addCouse() {
      int count = 0;
      cout << "Courses count: ";
      cin >> count;
    
      while (count-- > 0) {
        Course course;
        cout << "Course ID: ";
        cin >> course.id;
    
        cout << "Course name: ";
        cin >> course.name;
    
        courses.push_back(course);
      }
    }
    
    void Gradebook::printCourse() {
      cout << "There are " << courses.size() << " courses" << endl;
      for (std::list<Course>::iterator i = courses.begin(); i != courses.end(); ++i) {
        cout << "    ID: " << i->id << " name: " << i->name << endl;
      }
    }
    

    If you wish to use std::vector, only the addCourse would change:

    void Gradebook::addCouse() {
      int count = 0;
      cout << "Courses count: ";
      cin >> count;
      courses.reserve(count);
    
      while (count-- > 0) {
        Course course;
        cout << "Course ID: ";
        cin >> course.id;
    
        cout << "Course name: ";
        cin >> course.name;
    
        courses.push_back(course);
      }
    }