Вызвано исключение: нарушение доступа для чтения. this->

У меня класс Студент и класс Группа, который содержит массив объектов Студент. Не могу решить проблему. Почитала информацию по этому поводу, к сожалению так и не поняла.

class Group {
    Student** students;
    unsigned int group_size;
    int course;
public:
    Group();
    Group(Student* _students[], unsigned int _group_size, int __course);
    Group(const Group& other);
    ~Group();
    void AddStudent();
    void showInfo();
};

Group::Group() : students(nullptr), group_size(1), course(1) {};
Group::Group(Student* _students[], unsigned int _group_size, int _course) {
    students = new Student * [_group_size];
    for (int i = 0; i < _group_size; i++) {
        students[i] = _students[i];
    }
    this->group_size = _group_size;
    this->course = _course;
}
Group::~Group() {
    for (int i = 0; i < group_size; i++) {
        delete students[i];
    }

    delete[] students;
}
Group::Group(const Group& other) {
    for (int i = 0; i < other.group_size; i++)
    {
        students[i] = new Student(*other.students[i]);
    }
    group_size = other.group_size;
    course = other.course;
}

void Group::AddStudent() {

    Student** st = new Student * [this->group_size + 1];

    for (int i = 0; i < this->group_size + 1; i++)
    {
        st[i] = this->students[i];
    }
    delete[] this->students;
    this->students = st;
    students[this->group_size]->Student::enterInfo();
    this->group_size++;
}
void Group::showInfo() {

    if (group_size > 0) {
        for (int i = 0; i < group_size; i++)
        {
            cout << "Student - " << i + 1;
            students[i]->showInfo();
        }
    }
    else
    {
        cout << "Group is empty!!\n";
    }
}

210 строка


Ответы (1 шт):

Автор решения: DmitryK

Если указатель students в классе это указатель на массив объектов класса Student, то должно быть так:

class Group 
{
    Student* students; // один указатель, а не указатель на указатель

Конструктор по-умолчанию с ошибкой. Указатель nullptr а размер группы Вы почему-то инициализируете 1? Как будто у вас там 1 студент есть!

Group::Group() : students(nullptr), group_size(1), course(1) {}; 

Поскольку мы не видим класса Student здесь возможна ошибка - присваивание структуры структуре будет работать правильно только если она состоит из тривиальных типов, или если вы перегрузили operator=()

Group::Group(Student* _students[], unsigned int _group_size, int _course) {
    students = new Student[_group_size];
    for (int i = 0; i < _group_size; i++) 
        students[i] = _students[i];  // вот здесь возможна ошибка 

Деструктор неправильный. Он написан под указатель на массив указателей. В в нем удаляете память, которую не выделяли.

Group::~Group() {
//    for (int i = 0; i < group_size; i++)   // вот этого быть не должно
//        delete students[i];
    
    delete[] students;
}

Конструктор копирования Group::Group(const Group& other) тоже с ошибками. Вы тут динамически выделяете память под каждый объект Student, а надо:

  • проверить указатель, если массив уже выделен - удалить
  • выделить память под новое количество элементов
  • переприсвоить элементы

Ну и добавление - опять выделение памяти под массив указателей. А потом работа как с массивом объектов.

void Group::AddStudent() 
{
    Student* st = new Student[this->group_size + 1];
    for (int i = 0; i < this->group_size + 1; i++)
        st[i] = this->students[i];

    delete[] this->students;
    this->students = st;
    students[this->group_size]->Student::enterInfo();
    this->group_size++;
}

Если путаетесь в динамических выделениях памяти, то проще всего использовать динамический массив из стандартной библиотеки class Group { vector<Student> students;
Или хотя бы используйте умные указатели для работы с памятью std::unique_ptr<Student>

→ Ссылка