c ++类和垃圾数据

时间:2014-04-23 16:55:20

标签: c++ class pointers garbage

对于我今年的上一个项目,我正在尝试用C ++编写成绩簿程序。使用类与结构,new和delete而不是malloc和free,我将重新创建我以前用C编写的作业。在我的上一个问题中有人告诉我停止使我的变量私有,因为我有一个指向我的主类的类的指针。

在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;
 };

在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;

 }

}

当我运行addCourse函数然后运行printCourse它可以工作。

然后我运行addStudent函数然后运行printStudent它可以工作。

问题:

在我添加学生并重新运行printCourse后,我会在课程[i] .course_id打印时获得垃圾数据。但只有当i = 2时。课程[i = 2] .name仍然使用正确的数据打印。我可以添加更多课程并添加更多学生,他们打印出来就好了,只有当i = 2时,course_id才能获得垃圾数据。我已经被困了几天而且我试着以不同的方式看待它,直到@wheaties提到我以前做的事情是正确的并且它应该是公开的。你们其中一个人能帮助我吗?

4 个答案:

答案 0 :(得分:1)

您的问题:

以下内容:

courses[courses->count_courses].course_id;

不做你想做的事。它将courses视为一组Course对象,而实际上它只是一个(堆分配的)对象。因此,只要count_courses增加,就可以访问单个现有Course对象之外的内存,正如您已经观察到的那样,它只产生垃圾。

如何修复

正确的“C ++”方式是使用std::vector而不是CourseStudent列表的指针。但是,如果真的必须使用手动内存分配,则必须:

  1. count_coursescount_students移出相应的类并进入CourseBook。每个学生或课程对象代表一个单独的课程/学生,因此将计数存储在其中是没有意义的。
  2. 使用“array new”分配内存:courses = new Course[count];。当然,你必须将配置移出构造函数,然后在addCourse中进行,而你知道那里有多少项
  3. 不要忘记释放分配的内存..

答案 1 :(得分:1)

问题:

Gradebook::Gradebook()中,您构建了一个Course

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

Student同样如此。您需要构造一个数组或使用一个STL的容器。对于这种情况,我建议使用std::liststd::deque。一个简单的用法是:

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;
  }
}

如果您希望使用std::vector,则只会更改addCourse

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);
  }
}

答案 2 :(得分:0)

如果有

Course * courses;

这意味着您有一个包含地址的变量到包含Course的内存区域。您可以通过编写

来访问内存区域(在使用newmalloc建立之后)
*courses = ...;

courses->name.

但是,C(和C ++)允许您对此指针应用索引:

courses[i]

这只是

*(courses + i)

,即按照你所获得的指针,通过courses增加i Course的大小来获得指针。

考虑new Course为单个Course提供内存,然后查看addCourses中的循环内容...

如果您使用std::vector,则无需动态内存分配。

答案 3 :(得分:0)

课程类中只有一个对象,您在Gradebook :: Gradebook()的构造函数中创建

您应该尝试创建任意数量的课程对象。你可以通过

来做到这一点
  Gradebook::addCourse() {

 int i, loop=0;

 cout << "Enter number of Courses: ";
 cin >> loop;
 //add these lines here and remove them form Gradebook constructor
 courses = new Course[loop];
 courses->count_course=0;
 courses->course_id = 0;
 //^^^^^

 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++;

 } 

}