【问题标题】:C++ read memory faildC++ 读取内存失败
【发布时间】:2020-11-28 21:43:24
【问题描述】:

我有 2 节课:

class b_class
{
public:
    int time_viewed;
    int parent_course;

    b_class()=default;

    b_class(int parent_course):time_viewed(0), parent_course(parent_course){
    }
};

和:

class b_course
{
public:

    int course_id;
    int num_of_classes;
    b_class **classes;

    b_course(int course_id,int num_of_classes);
};

在后者中我写了以下代码:

b_course::b_course(int course_id,int num_of_classes) {
    this->course_id=course_id;
    this->num_of_classes=num_of_classes;
    classes=new b_class*[num_of_classes*sizeof(b_class*)];
    for (int i=0;i<num_of_classes;i++)
    {
        classes[i]->time_viewed=0;
        //classes[i]->parent_course=course_id;
    }
}

但我遇到了一个错误,因为我试图访问一些不应访问的内存。

从 0x7000000000000000 读取内存失败(读取 4 个字节中的 0 个)

有人知道这是什么原因吗?

classes 是指向b_class 的指针数组

【问题讨论】:

  • classes=new b_class*[num_of_classes*sizeof(b_class*)]; 是可疑的。我希望 classes=new b_class[num_of_classes]; 然后有更多代码来“新建”每个数组元素。
  • new int[7] 将分配一个由 7 个 int 元素组成的数组,而不是由 7 个指向 int 的指针组成的数组
  • 请不要从您的问题中删除代码,这会使答案难以理解。
  • 根据this help page,您不得删除您的问题,因为这会使现有答案无效。因此,您的原始问题已恢复。请不要再次删除。
  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发布,您已根据 CC BY-SA 4.0 许可授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。

标签: c++ class memory


【解决方案1】:

您正在分配一个不指向任何有效对象的指针数组。而且您为数组分配的空间比实际需要的要多。

b_course::b_course(int course_id,int num_of_classes) {
    this->course_id = course_id;
    this->num_of_classes = num_of_classes;
    classes = new b_class*[num_of_classes]; // <- get rid of sizeof() here
    for (int i = 0; i < num_of_classes; i++)
    {
        classes[i] = new b_class(/*course_id*/); // <- add this
        classes[i]->time_viewed = 0;
    }
}

话虽如此,更好的选择是分配对象数组而不是指针数组,例如:

class b_course
{
public:

    int course_id;
    int num_of_classes;
    b_class *classes;

    b_course(int course_id, int num_of_classes);
};

b_course::b_course(int course_id, int num_of_classes) {
    this->course_id = course_id;
    this->num_of_classes = num_of_classes;
    classes = new b_class[num_of_classes];
    for (int i = 0; i < num_of_classes; i++)
    {
        classes[i].time_viewed = 0;
        //classes[i].parent_course = course_id;
    }
}

无论哪种方式,由于您是动态分配对象,因此请务必遵循Rule of 3/5/0,同时实现析构函数以释放对象和数组,以及复制构造函数和复制赋值运算符以从一个b_course 到另一个。

处理所有这些的最佳方法是使用std::vector 而不是new[],并让编译为您处理细节,例如:

#include <vector>

class b_course
{
public:

    int course_id;
    std::vector<b_class> classes;

    b_course(int course_id,int num_of_classes);
};

b_course::b_course(int course_id,int num_of_classes) {
    this->course_id=course_id;
    this->classes.resize(num_of_classes);
    for (int i=0;i<num_of_classes;i++)
    {
        classes[i].time_viewed=0;
        //classes[i].parent_course=course_id;
    }
}

【讨论】:

  • 请不要我希望它是一个指针数组,不要改变它
  • @john 请注意,您问的问题是“这是什么原因?”正确答案在前两句。它确实回答了你的问题。剩下的答案是一个很好的“如何解决它?”添加在。如果你绝对需要一个指针数组,你应该在问题中说出来,也许解释一下你为什么需要它
  • @john 还请注意,如果您想学习 C++,那么这是使用 std::vector 的理由,而不是不使用它的理由
  • 我同意@idclev463035818。太多的教师和教科书将 C++ 视为只是添加了 OOP 的 C,这是不正确的。 C 和 C++ 已经演变成非常不同的语言。有很多 good C++ books 以正确的方式教授 C++。
  • @john 建议你看这个:Stop teaching C,这个标题相当挑衅,但谈话很好地解决了问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 2014-05-05
  • 2019-10-07
  • 1970-01-01
相关资源
最近更新 更多