我有一个" Class"具有字符串名称和数组"学生"对象。 "学生" class有一个名字,并且有#34; Grades"。 "成绩" class是一个双打数组。
在主类中,我创建了一个Grades对象和一个Student对象。我用它测试了一些函数,一切运行良好:
int main(){
cout << fixed << setprecision(2);
Grades test = Grades ("5 - 90.0 85.0 95.5 77.5 88.0");
cout << test.toString() << endl;
cout << "\nSum = " << test.getSum() << endl;
cout << "Num grades = " << test.getNumGrades() << endl;
cout << "Low grade = " << test.getLowGrade() << endl;
cout << "High grade = " << test.getHighGrade() << endl;
Student stu = Student("Billy Bob", "5 - 90 85 95.5 77.5 88");
cout << stu.toString() << endl;
cout << "\nSum = " << stu.getSum() << endl;
cout << "Average = " << stu.getAverage() << endl;
cout << "Average after dropping low grade = " << stu.getAverageMinusLow() << endl;
cout << "Low grade = " << stu.getLowGrade() << endl;
cout << "High grade = " << stu.getHighGrade() << endl;
}
但是当我添加这行时:
Class testClass = Class("Comp Sci 1", 3);
然后运行程序,它有一个Stack Overflow错误。 &#34; Gradebook.exe中0x0033EAB7的第一次机会异常:0xC00000FD:堆栈溢出(参数:0x00000000,0x003D2000)。&#34;
如果存在此异常的处理程序,则可以安全地继续该程序。 是因为对象太多而且每个对象都是另一个对象的成员吗?有没有办法去&#34;删除&#34;我的测试&#34;和&#34; stu&#34;在此行之前创建的对象?
这是我的&#34; Class&#34;构造函数供参考:
class Class{
private:
string name;
Student studentList[100];
int numStudents;
public: Class(string className, int numStudents1);
Class();
}
Class:: Class(string className, int numStudents1){
name = className;
numStudents = numStudents1;
}
Class:: Class(){
name = "";
numStudents = 0;
}
此错误是否显示,因为我的&#34; studentList&#34; Class对象中的Student数组未在构造函数中实例化?
答案 0 :(得分:0)
函数中的每个变量声明都位于堆栈中,声明在函数外部的变量是静态变量并使用data segment。
Class testClass("Comp Sci 1", 3);
int main(){
这在某些方面也很糟糕,但不会导致堆栈溢出。
答案 1 :(得分:-1)
这种设计显然是错误的。
你应该在Student
里面有一个矢量或类似的容器来容纳所有成绩,并在Class
内有一个类似的容器来容纳所有学生。你说你的老师不允许你使用矢量,这对你的水平没有多大意义,但也许他希望你创建自己的容器类?再说一次,你似乎还没到那里,所以这是一种悖论。
你的问题是你有100个学生在课堂上分配了足够的存储空间,那100个学生可能会有很多成绩,所以这个课程可能最终变得庞大,太大而无法放入堆叠,这就是为什么它溢出。通过这种方式,课程加上学生加上成绩创造了一大块&#34; flat&#34;记忆。当你在没有编译器优化的情况下使用那种形式的实例化Class testClass = Class(...)
时,它只创建一个而不是两个对象,只是将后者分配给前者。修复类构造函数(你应该修复另一个)可能会解决溢出问题,但它不能修复你的设计问题。
将Class
这样的大结构放在内存中并不平坦,这是一种更为简单和建议的良好做法。让它平坦实际上更复杂但可能具有其他优点(例如性能或内存效率),并且仍然可以安全地使用动态分配,但在您的情况下,您对顶级效率不感兴趣,但有了解并因此有一个好的设计。
另外,正如评论中所提到的,创建具有成绩的学生是错误的,特别是将成绩作为字符串文字传递。如果这是一个你必须在实践中使用的真实课程,如果成绩尚未到来,你将如何在年初创建新学生的所有成绩?您的Student类构造函数应该只为学生传递一个名称,而应该有一个addGrade()
成员函数。
那个Class对象预先分配长度为100的静态数组怎么样?如果你只有3名学生,那么有97名学生会浪费内存。如果你需要超过100名学生怎么办?你的程序崩溃了。这就是为什么你应该使用一个容器,只有你需要的学生。我只能假设学生班内发生了同样可怕的事情。那些类型的&#34;技术&#34;通常用于旧的C代码,这可能是你的老师所困扰的,但当然不建议用于教授现代C ++。