You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中创建带构造函数的类对象数组及添加对象时程序崩溃问题

嘿,我来帮你揪出程序崩溃的根源,咱们一步步拆解问题:

核心崩溃原因:非法内存访问(数组越界)

你的程序崩溃直接来自这段代码:

Student *s4;
for(int i = 0; i < 2; i++) {
 s4=s3;
}
s4[3].addStd(2,"mary");

这里的问题出在:

  • s3是一个长度为2的Student数组,它的有效索引只有0和1(数组元素从0开始计数)。
  • 你让s4指向s3的首地址后,直接访问s4[3]——这已经超出了数组的合法范围,属于访问非法内存,操作系统会直接终止程序,也就是你看到的崩溃。
  • 另外那个循环for(int i = 0; i < 2; i++) { s4=s3; }完全是多余的,循环两次赋值同一个地址,没有任何实际作用。
修复方案:动态管理学生对象

如果你想添加新的学生,不能直接在固定大小的数组上越界操作,推荐两种更安全的方式:

方式1:使用C++标准库的vector(推荐)

vector可以自动管理动态扩容,不用手动处理内存,代码更简洁安全:

#include <iostream>
#include <string>
#include <vector> // 新增头文件
using namespace std;

class Student {
 int id;
 string name;
 float letter[5];
public:
 Student(int studentId) : id(studentId), name("ali") { // 改用初始化列表
 for (int i = 0;i<5;i++) {
 letter[i] = 12;
 }
 }
 Student(int studentId, string Sname, float d[5]) : id(studentId), name(Sname) {
 for (int i = 0; i < 5; i++) {
 letter[i] = d[i];
 }
 }
 void updateInfo(int studentId, string Sname) { // 重命名方法,语义更准确
 id = studentId;
 name = Sname;
 for (int i = 0; i < 5; i++) {
 letter[i] = 15;
 }
 }
 void PrintStd() {
 cout << id << "\t" << name << "\t";
 for(int i=0;i<5;i++) {
 cout << letter[i] << "\t";
 }
 cout << endl;
 }
};

int main() {
 Student S1(1);
 float dd1[5] = {20,20,20,20,20};
 Student S2(2,"jack",dd1);

 // 用vector存储学生
 vector<Student> students;
 students.emplace_back(1); // 直接构造第一个学生
 students.emplace_back(2,"fered",dd1); // 构造第二个学生

 // 添加新学生:先构造临时对象,再修改信息
 students.emplace_back(0); 
 students.back().updateInfo(3,"mary"); // 修改最后一个学生的信息

 // 打印所有学生
 cout << "所有学生信息:" << endl;
 for (auto& student : students) {
 student.PrintStd();
 cout << "*************" << endl;
 }

 return 0;
}

方式2:手动管理动态数组

如果你想坚持用指针和数组,需要手动重新分配内存、复制旧数据,记得最后释放内存:

// 类定义和之前一致,略去
int main() {
 float dd1[5] = {20,20,20,20,20};
 int currentSize = 2;
 // 动态分配初始数组
 Student *s4 = new Student[currentSize]{Student(1), Student(2,"fered",dd1)};

 // 要添加新学生,先扩容数组
 int newSize = currentSize + 1;
 Student *temp = new Student[newSize];
 // 复制旧数据
 for(int i=0; i<currentSize; i++) {
 temp[i] = s4[i];
 }
 // 设置新学生信息
 temp[2].updateInfo(3,"mary");

 // 释放旧内存,更新指针
 delete[] s4;
 s4 = temp;
 currentSize = newSize;

 // 打印所有学生
 cout << "所有学生信息:" << endl;
 for(int i=0; i<currentSize; i++) {
 s4[i].PrintStd();
 cout << "*************" << endl;
 }

 // 最后记得释放动态分配的内存
 delete[] s4;
 return 0;
}
额外优化建议
  • 构造函数的参数名size容易混淆(它实际是学生ID),建议改成studentId,代码可读性更强。
  • 尽量用初始化列表初始化类成员变量(像上面修复代码里那样),比在构造函数体内赋值更高效规范。
  • addStd方法的语义不准确——它是修改当前对象的信息,不是添加新对象,建议改名为updateInfo或者setStudentInfo。

内容的提问来源于stack exchange,提问作者user3115252

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:42:49