【发布时间】:2021-01-29 16:06:39
【问题描述】:
所以我正在创建一个程序,它实现了代表一所学校及其学生和课程的几个类。当我尝试打印出 studentCoursePairs[] 数组中的所有 Taken 对象时出现分段错误,该数组表示参加特定课程的学生对象。我认为我的分段错误来自 School.cc 中的 addTaken() 函数,它的工作是查找具有给定学生编号和课程 ID 的学生对象和课程对象,然后使用找到的学生和课程创建一个新的 Taken 对象对象和等级。然后我尝试将这个新对象添加到 Taken 集合的后面,即 studentCoursePairs。
当我注释掉 studentCoursePairs[i]->print() 时,分段错误就消失了。我不确定自己做错了什么,希望能得到一些帮助。
我不确定是否需要除 School.cc 之外的其他课程,但我还是将它们包括在内以帮助理解。
学校.cc:
#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;
for(int i = 0; i < numTaken; ++i){
if((studentsCollection->find(number, &s)) && (coursesCollection->find(code, &c))){
Taken* taken = new Taken(s, c, grade);
studentCoursePairs[i] = taken;
++numTaken;
}
}
}
void School::printTaken(){
cout << name << " === TAKEN: "<< endl;
for(int i = 0; i < sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0]); ++i){
studentCoursePairs[i]->print(); //seg fault
}
}
其他文件:
StudentCollection.cc
bool StudentCollection::find(string num, Student** s){
for(int i = 0; i < size; ++i){
if(students[i]->getNumber() == num){ //find student number
*s = students[i];
}
}
}
CoursesCollection.cc
bool CoursesCollection::find(int id, Course** c){
for(int i = 0; i < numCourses; ++i){
if(courses[i]->getId() == id){ //find course id
*c = courses[i];
}
}
}
我还有一个 Student 类和 Course 类,它们只是声明和初始化学生的姓名、课程、gpa 以及课程代码、讲师、姓名、课程年份等信息。
【问题讨论】:
-
不要猜测,而是在调试器下运行程序并研究崩溃时的程序状态。
-
既然我已经阅读了您的代码,请尝试回答以下问题:如果只有 3 个学生-课程对,
studentCoursePairs[10]中的内容是什么?对studentCoursePairs[10]->print()调用有什么影响? -
你为什么要使用拥有指针和
new来处理所有事情?默认情况下使用值和集合,必要时使用智能指针。 -
for 循环仅打印 studentCoursePairs 数组具有的元素数。因此,如果只有 3 对,则 sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0]) 不会让它打印到前 3 对之后。
-
数组不是这样工作的。您将其声明为
Taken* studentCoursePairs[MAX_PAIRS];,因此表达式将始终返回MAX_PAIRS。您将需要另一种方法来跟踪占用的插槽数,或者将插槽标记为空(然后在遍历数组时检查该标记)。
标签: c++ arrays pointers printing segmentation-fault