首页 > 解决方案 > 当我尝试创建自定义对象数组然后使用它们时,出现堆栈转储错误。我究竟做错了什么?

问题描述

我运行时遇到此错误

0 [main] 测试 449 cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 test.exe.stackdump

我对 c++ 编程比较陌生,我来自 python,我将链接代码,但谁能告诉我发生了什么以及问题可能是什么?

#include <string>

#include <iostream>
using namespace std;

struct grade
{
    int totalCourses;
    string mNumber;
    string *courses = new string[totalCourses];

    grade(int numOfCourses = 10)
    {
        totalCourses = numOfCourses;
    }
    
    ~grade()
    {
        delete[] courses;
    }
};

int main()
{
    int totalGrades;
    cout << "Enter num of grades: ";
    cin >> totalGrades;
    grade *gradeArray = new grade[12];
    grade newGrade(6);
    newGrade.mNumber = "M12345678";
    cout << newGrade.mNumber << '\n';
    gradeArray[0] = newGrade;
    delete[] gradeArray;
    return 0;
}

标签: c++structruntime-errordynamic-memory-allocation

解决方案


这个问题有点难以回答,因为有两个未定义行为的来源。任何一个都可能导致崩溃,但同时,任何一个似乎都可以按预期工作。有些人觉得这很奇怪,但这就是未定义行为在 C++ 中的工作方式;这不是“允许除预期之外的任何行为”,而只是“允许任何行为”

问题 1

类成员在构造函数主体的左大括号之前初始化。这是您的构造函数的注释版本。

    grade(int numOfCourses = 10)   // Constructor starts
    // Members `totalCourses`, `mNumber`, and `courses` are initialized here. However,
    // you specified an initial value only for `courses`, so effectively you initialize:
    // courses = new string[/* unspecified value */];
    {
        // It is only here, *after* the opening brace, that `totalCourses` gets a value.
        totalCourses = numOfCourses;
    }

您必须在初始化这些相关字段的方式上保持一致。如果一个依赖于一个参数,那么两者都依赖于一个参数。使用初始化列表来完成此操作。

    grade(int numOfCourses = 10) :
        totalCourses(numOfCourses),
        courses(new string[numOfCourses]) // Use the parameter for robustness (the order
    {}                                    // of fields here is not always the order in
                                          // which the fields are initialized).

问题 2

您已经定义了一个(非平凡的)析构函数,但没有遵循三规则。请点击链接了解为什么需要定义复制构造函数和复制赋值运算符的详细信息。(如果这是唯一的问题,那么这个问题将作为重复问题保持关闭。)


推荐阅读