Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-在统计分配的数组中打印对象会导致分段错误_C++_Arrays_Pointers_Printing_Segmentation Fault - Fatal编程技术网

C++ C++;-在统计分配的数组中打印对象会导致分段错误

C++ C++;-在统计分配的数组中打印对象会导致分段错误,c++,arrays,pointers,printing,segmentation-fault,C++,Arrays,Pointers,Printing,Segmentation Fault,因此,我正在创建一个项目,该项目实施了代表一所学校及其学生和课程的几个课程。当我试图打印studentCoursePairs[]数组中的所有对象时,我遇到了一个分割错误,该数组表示参加特定课程的学生对象。我认为我的分段错误来自School.cc中的addtake()函数,它的工作是查找具有给定学生编号和课程id的学生对象和课程对象,然后使用找到的学生对象和课程对象以及成绩创建一个新的take对象。然后,我尝试将这个新对象添加到所选集合的后面,即studentCoursePairs 当我注释掉st

因此,我正在创建一个项目,该项目实施了代表一所学校及其学生和课程的几个课程。当我试图打印studentCoursePairs[]数组中的所有对象时,我遇到了一个分割错误,该数组表示参加特定课程的学生对象。我认为我的分段错误来自School.cc中的addtake()函数,它的工作是查找具有给定学生编号和课程id的学生对象和课程对象,然后使用找到的学生对象和课程对象以及成绩创建一个新的take对象。然后,我尝试将这个新对象添加到所选集合的后面,即studentCoursePairs

当我注释掉studentCoursePairs[I]->print()时,分段错误消失了。我不确定我做错了什么,希望能得到一些帮助

我不确定是否需要School.cc以外的其他课程,但我还是加入了它们,以帮助理解

School.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
    }   
}
#包括
#包括
使用名称空间std;
#包括
#包括“School.h”
学校::学校(字符串s1):名称(s1){
numTaken=0;
}
void School::addtake(字符串编号、整数代码、字符串等级){
学生*s=nullptr;
课程*c=nullptr;
对于(int i=0;i查找(编号和编号))&((课程集合->查找(代码和编号))){
采取*采取=新采取(s、c、等级);
学生课程表[i]=参加;
++纽特肯;
}
}
}
void School::printTake(){
cout getId()==id){//查找课程id
*c=课程[i];
}
}
}

我还有一个学生类和课程类,它只声明和初始化学生的姓名、课程、gpa以及课程代码、讲师、姓名、课程年份等信息。

您的学校对象有两个主要问题。让我们从您在问题中发布的内容开始:

void School::printTaken(){
    cout << name << " === TAKEN: "<< endl;
    for(int i = 0; i < sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0]); ++i){
        studentCoursePairs[i]->print(); //seg fault
    }   
}
因此
sizeof(studentCoursePairs)==MAX\u PAIRS*sizeof(studentCoursePairs[0])

相反,您只希望在实际包含有效指针的前几个插槽上循环。您有一个变量:
numTaken
。因此,将条件更改为
i
,打印循环将正常工作

第二个主要问题是
addtake

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::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;
    }
}
找出如何处理传递的组合无效或超过MAX_PAIRS组合的情况是留给您的练习

编辑:课程集合中还有第三个主要问题:将一个对象
new Course()
作为数组处理时,为其分配空间,并将结果存储在局部变量而不是成员中。您的构造函数应该看起来像:

CoursesCollection::CoursesCollection(){
    courses = new Course*[MAX_COURSES];
    numCourses = 0;
}
或者,使用成员初始值设定项列表:

CoursesCollection::CoursesCollection() 
  : courses(new Course*[MAX_COURSES]), numCourses(0) {}

你的学校目标有两个主要问题。让我们从您在问题中发布的内容开始:

void School::printTaken(){
    cout << name << " === TAKEN: "<< endl;
    for(int i = 0; i < sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0]); ++i){
        studentCoursePairs[i]->print(); //seg fault
    }   
}
因此
sizeof(studentCoursePairs)==MAX\u PAIRS*sizeof(studentCoursePairs[0])

相反,您只希望在实际包含有效指针的前几个插槽上循环。您有一个变量:
numTaken
。因此,将条件更改为
i
,打印循环将正常工作

第二个主要问题是
addtake

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::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;
    }
}
找出如何处理传递的组合无效或超过MAX_PAIRS组合的情况是留给您的练习

编辑:课程集合中还有第三个主要问题:将一个对象
new Course()
作为数组处理时,为其分配空间,并将结果存储在局部变量而不是成员中。您的构造函数应该看起来像:

CoursesCollection::CoursesCollection(){
    courses = new Course*[MAX_COURSES];
    numCourses = 0;
}
或者,使用成员初始值设定项列表:

CoursesCollection::CoursesCollection() 
  : courses(new Course*[MAX_COURSES]), numCourses(0) {}

不要猜测,而是在调试器下运行程序,并研究崩溃时的程序状态。现在我已经阅读了您的代码,请尝试回答以下问题:
studentCoursePairs[10]
如果只有3对学生-课程,那么其中有什么?对
studentCoursePairs[10]->print()
调用有什么影响?为什么要使用owning指针和
new
?默认情况下使用值和集合,必要时使用智能指针。for循环仅用于打印studentCoursePairs数组具有的元素数。因此,如果只有3对,那么sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0])不会让它打印超过前3对。这不是数组的工作方式。您将其声明为
taked*studentCoursePairs[MAX_PAIRS]
这样表达式将始终返回
MAX\u PAIRS
。您需要另一种方法来跟踪占用的插槽数量,或者将插槽标记为空(然后在遍历数组时检查该标记)。不要猜测,而是在调试器下运行程序,并研究崩溃时的程序状态。现在我已经阅读了您的代码,试着回答以下问题:
studentCoursePairs[10]
如果只有3对学生-课程,那么其中有什么?对
studentCoursePairs[10]->print()
调用有什么影响?为什么要使用owning指针和
new
?默认情况下使用值和集合,必要时使用智能指针。for循环仅用于打印studentCoursePairs数组具有的元素数。因此,如果只有3对,那么sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0])不会让它打印超过前3对。这不是数组的工作方式。您将其声明为
taked*studentCoursePairs[MAX_PAIRS]
这样表达式将始终返回
MAX\u PAIRS
。您需要另一种方法来跟踪占用的插槽数量,或者将插槽标记为空(然后在遍历阵列时检查该标记)。
Course*courses=new Course()--您忘记了吗