为什么我在C++中的类中插入值时出现运行时错误

Why do I have a run-time Error inserting values into classes in C++

本文关键字:运行时错误 插入 C++ 为什么      更新时间:2023-10-16

我需要一些帮助来解决这个问题。我有一个名为"成绩"的类,其中包含指向"学生"类的指针。

class Grades {
    int numofstuds;
    Student** studs;
public:
    void insertgrades();
    void printgrades();
};
class Student {
    int id;
    int grade;
public:
    void getId();
    void getGrade();
    void printgrade();
};

我正在尝试将学生插入数组螺柱中:

void Grades::insertgrades() {
    int i;
    cout << "How many students ?" << endl;
    cin >> numofstuds;
    studs = new Student*[numofstuds];
    for (i = 0; i < numofstuds; i++) {
        studs[i]->getId();
        studs[i]->getGrade();
    }
}

"插入等级"是类成绩中的一个内部函数。getId 和 getGrade 是类"学生"中的内部函数,它们运行良好,我已经检查过它们:

void Student::getId() {
    do {
        cout << "Enter id" << endl;
        cin >> id;
    } while (id<0);
}
void Student::getGrade() {
    cout << "Enter grade:" << endl;
    cin >> grade;
}

这是主要的:

int main() {
    Grades a;
    a.insertgrades();
    return 0;
}

一旦我尝试将值插入 Id 或等级,我就会立即出现运行时错误。请帮忙!伊桑。

MikeCAT的回答是正确的,但是请注意,您正在做的事情很可能导致内存泄漏。显然我还没有看到你的类析构函数 - 但是,除非您仔细迭代 Studs 中的每个指针,调用 delete [],然后在 Studs 上调用 delete [] - 你最终会陷入一大堆泄露的内存。

我将假设从您对语言的使用中,您更熟悉引用计数语言(如 VisualBasic) - C++使用新分配内存并不能保证垃圾回收。由于您不存储numberofstuds您将永远无法释放MikeCAT答案中分配的内存。

如果可以使用 C++11,请考虑以下代码片段,以获取处理此问题的内存安全方法。

#include <memory>
#include <vector>
class Student;
class Grades {
    int numofstuds;
    std::vector<std::shared_ptr<Student> > studs;
public:
    void insertgrades();
    void printgrades();
};

和刀片牌号例程:

void Grades::insertgrades() {
    int i;
    std::cout << "How many students ?" << std::endl;
    std::cin >> numofstuds;
    studs.resize(numofstuds);
    for (auto Each_Student : studs) 
    {
        Each_Student.reset(new student())
        Each_Student->getId();
        Each_Student->getGrade();
    }
}

但是,如果您必须使用原始指针(较旧的编译器或较差的评分主体),除了 MadCat 的答案外,请考虑以下析构函数

~Grades()
{
    for (i = 0; i < numofstuds; i++) 
    {
        delete studs[i];
    }
delete [] studs;
}

[/编辑]

我想补充一点,您存储数据的方法并没有,但是您可以更简单地做到这一点。与其创建指针数组来存储数据,不如改为分配对象数组。

class Grades 
{
    //snipped out everything else
    Student* studs;
}
void Grades::insertgrades() 
{
    int i;
    cout << "How many students ?" << endl;
    cin >> numofstuds;
    studs = new Student[numofstuds];
    for (i = 0; i < numofstuds; i++) {
        studs[i].getId();
        studs[i].getGrade();
    }
}

在C++中,指针是"数据内存中的地址",数组是"一组数据的内存中的地址",因此以下代码应该可以帮助您理解为什么上述工作。

char A;
//the following pointer will *point to the location of A*
char * A_p = & A;
char Array[100];
//this pointer will *point to the data set Array*
char * Array_p = Array;
//this pointer *points to a newly allocated set of data*
char * B_p = new char [100];
//indeed, we can also do this 
//Set A to first character of array
A = *Array_p
A = Array_P[0]
A = *Array
A = Array[0]
//all of these do the same thing, as *when using an array, you're really using a pointer
delete [] B_P;

您只创建了"框"来存储指向Student的指针,但没有存储有效的指针。

您必须在使用前创建学生。

void Grades::insertgrades() {
    int i;
    cout << "How many students ?" << endl;
    cin >> numofstuds;
    studs = new Student*[numofstuds];
    for (i = 0; i < numofstuds; i++) {
        studs[i] = new Student(); // add this line
        studs[i]->getId();
        studs[i]->getGrade();
    }
}

感谢您的即时回复!多亏了@MikeCAT,我已经解决了这个问题。我添加了另一个函数来实际创建一个学生:

Student* createstud() {
    Student* News = new Student;
    return News;
}

然后我像这样改变我的函数:

void Grades::insertgrades() {
    int i;
    cout << "How many students ?" << endl;
    cin >> numofstuds;
    studs = new Student*[numofstuds];
    for (i = 0; i < numofstuds; i++) {
        **studs[i] = createstud();**
        studs[i]->getId();
        studs[i]->getGrade();
    }
}

不知道为什么创建 Students** 数组是个坏主意,因为我打算将来删除学生,这样更容易更改数组内的指针,不是吗?