C++类数组项目运行崩溃无报错问题求助
嘿,我来帮你拆解下程序崩溃的原因,还有几个影响功能的小问题,一个个来:
1. Main函数里的两个致命错误
你这段main代码直接导致了崩溃:
int x; cin>>x; for(int i=0;i<x;i++) { Module Module[x]; Module[x].Run_Time(); }
- 非标准变长数组(VLA):
Module Module[x];是C语言的写法,C++标准并不支持这种动态长度的数组声明(虽然部分编译器有扩展,但属于非标准行为,移植性差)。 - 数组越界访问:数组的索引范围是
0到x-1,你写的Module[x].Run_Time();直接访问了超出数组边界的元素,这会触发未定义行为,直接导致程序崩溃。
修复方案:
用C++标准的std::vector来存储多个Module对象,它会自动管理内存,安全又方便:
#include <vector> // 记得包含头文件 int main() { int x; cout << "请输入模块数量: "; // 加上提示,用户知道要输入什么 cin >> x; cin.ignore(); // 关键:忽略输入x后留下的换行符,避免后续getline读空字符串 std::vector<Module> modules(x); // 创建x个Module对象的容器 for(int i=0;i<x;i++) { cout << "\n--- 输入第" << i+1 << "个模块的信息 ---\n"; modules[i].Run_Time(); } return 0; }
2. 类中柔性数组的错误使用
你的Module类里定义的这两个数组是问题核心之一:
int Assignment_1_Question_Nr[]; int Assignment_2_Question_Nr[];
这是C语言的柔性数组成员,C++标准不支持这种写法,而且你完全没给这些数组分配内存,后续通过Assignment_1_Question_Nr[i]=A1QP; 访问时,会直接读写非法内存,必然导致崩溃。
修复方案:
改用std::vector<int>替代裸数组,它会自动处理内存分配和释放:
#include <vector> // 包含头文件 class Module { private: string Module_Name; int Assignment_1_Total_Points; int Assignment_2_Total_Points; int Assignment_1_Max; int Assignment_2_Max; std::vector<int> Assignment_1_Question_Nr; // 替换成vector std::vector<int> Assignment_2_Question_Nr; float Assignment_1_Percentage; float Assignment_2_Percentage; // 注意:你之前拼写错成了Perventage float Semester_Final_Percentage; // 把public里的n、m等变量移到private,符合封装原则 int n=0; int m=0; int SumA1=0; int SumA2=0; public: // 保留原来的成员函数即可 Module() = default; // 构造函数可以简化,vector默认是空的 void Set_Module_Name(); void set_Assignment_Question_Sizes(); // ... 其他成员函数
然后修改set_Assignment_Question_Sizes,给vector调整大小:
void set_Assignment_Question_Sizes() { cout<<"请输入作业1的题目数量: "; cin>>n; cout<<"请输入作业2的题目数量: "; cin>>m; Assignment_1_Question_Nr.resize(n); // 调整vector大小,匹配题目数量 Assignment_2_Question_Nr.resize(m); cin.ignore(); // 忽略换行符,避免影响后续getline }
另外,Get_Set_Assignment_Question_Points里有个笔误:把作业2的分数写到了作业1的数组里,要修正:
// 原来错误的代码:Assignment_1_Question_Nr[j]=A1QP; Assignment_2_Question_Nr[j]=A2QP; // 改成这个
3. 整数除法导致百分比计算错误
在Get_Assignment_Marks里,你用了整数除法:
Assignment_1_Percentage=(Assignment_1_Total_Points/Assignment_1_Max)*100;
因为两个操作数都是int类型,会触发整数除法,比如80分满分100,80/100结果是0,乘以100还是0,完全不符合预期。
修复方案:
把其中一个操作数转成浮点类型,强制触发浮点除法:
Assignment_1_Percentage = (static_cast<float>(Assignment_1_Total_Points) / Assignment_1_Max) * 100; Assignment_2_Percentage = (static_cast<float>(Assignment_2_Total_Points) / Assignment_2_Max) * 100;
4. 期末成绩未赋值
你的Show_Details函数里输出了Semester_Final_Percentage,但这个变量从来没被赋值过,会输出随机垃圾值。可以在Get_Assignment_Marks里补充计算逻辑(比如取两个作业的平均分,你可以根据需求调整):
void Get_Assignment_Marks() { Assignment_1_Percentage = (static_cast<float>(Assignment_1_Total_Points) / Assignment_1_Max) * 100; Assignment_2_Percentage = (static_cast<float>(Assignment_2_Total_Points) / Assignment_2_Max) * 100; Semester_Final_Percentage = (Assignment_1_Percentage + Assignment_2_Percentage) / 2; }
5. Getline读取空字符串的问题
当你用cin>>x或者cin>>n后,输入缓冲区会留下一个换行符,后续的getline(cin,name)会直接读取这个换行符作为空字符串,导致模块名称为空。解决方法是在每次用cin读取整数后,调用cin.ignore()忽略换行符(我在前面的代码示例里已经加了)。
内容的提问来源于stack exchange,提问作者Martin Sieburg




