[英]C++ - printing objects in statistically allocated array causes segmentation fault
因此,我正在創建一個程序,該程序實現了代表一所學校及其學生和課程的多個類。 當我嘗試打印出 studentCoursePairs[] 數組中的所有 Taken 對象時,我遇到了分段錯誤,該數組表示參加特定課程的 Student 對象。 我認為我的分段錯誤來自 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
}
}
附加文件:
學生收藏.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 以及課程代碼、講師、姓名、課程年份。
您的 School 對象有兩個主要問題。 讓我們從您在問題中發布的內容開始:
void School::printTaken(){
cout << name << " === TAKEN: "<< endl;
for(int i = 0; i < sizeof(studentCoursePairs)/sizeof(studentCoursePairs[0]); ++i){
studentCoursePairs[i]->print(); //seg fault
}
}
這個 for 循環將始終運行 MAX_PAIRS 次,因為這個變量被定義為
Taken* studentCoursePairs[MAX_PAIRS];
所以sizeof(studentCoursePairs) === MAX_PAIRS * sizeof(studentCoursePairs[0])
。
相反,您只想遍歷實際包含有效指針的前幾個插槽。 你有一個變量: numTaken
。 因此,將條件更改為i < numTaken
並且您的打印循環將起作用。
第二個主要問題是addTaken
:
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;
}
}
}
讓我們玩電腦,看看如果傳入的數字和代碼有效會發生什么:
0 < 0
為假)並且 numTaken 不遞增。 您可以addTaken
地調用addTaken
,它永遠不會改變numTaken
studentCoursePairs[0]
。 在第二次迭代中,您執行相同操作並使用等效對象覆蓋studentCoursePairs[1]
。 這可能不是預期的行為。 相反,您可能希望在studentCoursePairs[numTaken]
放置一個新對象並碰撞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 組合的情況留給您作為練習。
編輯:您的 CoursesCollection 中存在第三個主要問題:您為一個對象new Course()
分配空間,同時將其視為數組,並將結果存儲在局部變量而不是成員中。 您的構造函數可能看起來像:
CoursesCollection::CoursesCollection(){
courses = new Course*[MAX_COURSES];
numCourses = 0;
}
或者,使用成員初始值設定項列表:
CoursesCollection::CoursesCollection()
: courses(new Course*[MAX_COURSES]), numCourses(0) {}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.