I have 2 classes:
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){
}
};
and:
class b_course
{
public:
int course_id;
int num_of_classes;
b_class **classes;
b_course(int course_id,int num_of_classes);
};
In the latter I wrote the following code:
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;
}
}
But I'm getting an error because I am trying to access some memory which shouldn't be accessed.
read memory from 0x7000000000000000 failed (0 of 4 bytes read)
anyone know what is the reason for this?
classes
is an array of pointers to b_class
You are allocating an array of pointers that don’t point at any valid objects. And you are allocating more space for the array then you actually need.
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;
}
}
That being said, a better option is to allocate an array of objects instead of an array of pointers, eg:
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;
}
}
Either way, since you are allocating objects dynamically, be sure to follow the Rule of 3/5/0 by also implementing a destructor to free the objects and array, and a copy constructor and copy assignment operator to make copies of the array and objects from one b_course
to another.
The best way to handle all of this is to use a std::vector
instead of new[]
, and let the compile handle the details for you, eg:
#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;
}
}
Please not I want it to be an array of pointers and not to change that
@john note that the question you asked is "what is the reason for this?" The correct answer for that is in the first two sentences. It does answer your question. The rest of the answer is a nice "how to fix it?" add on. If you absolutely need an array of pointers you should say that in the question and perhaps explain why you need that
@john also note that if you want to learn C++ then this is a reason to use
std::vector
rather than a reason to not use itI agree with @idclev463035818. Too many teachers and textbooks approach C++ as if it were just C with OOP added on, which is not true. C and C++ have evolved into very different languages. There are plenty of good C++ books that teach C++ the right way.
@john suggest you to watch this: Stop teaching C, rather provocative title, but the talk nails the problem nicely