You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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++标准并不支持这种动态长度的数组声明(虽然部分编译器有扩展,但属于非标准行为,移植性差)。
  • 数组越界访问:数组的索引范围是0x-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

火山引擎 最新活动