Как создать динамический массив структур в классе С++

Есть класс, в котором помимо прочих членов есть член-структура, которая должна из себя представлять массив структур. То есть, когда создаем объект - в нем помимо прочих переменных, есть динамический массив структур. Хидер выглядит так:

#ifndef CALENDAR_H_
#define CALENDAR_H_
#include <string>
#include <iostream>

using namespace std; // Я знаю, что это плохая практика, но речь сейчас не об этом.

    class MounthCalendar{

    private:
      string m_MounthName;
      unsigned short int m_days;

      struct m_DaysGrid{

         string ms_centerName;
         unsigned short int ms_date;
         bool ms_weekend;

        } *DaysGrid = new m_DaysGrid[m_days]; //Решил, что так правильней, ошибок компиляции нет.

    public:

        MounthCalendar(); //Конструктор по умолчанию
        MounthCalendar(const string & mounthName, unsigned short int days = 0); //Произвольный конструктор
        ~MounthCalendar();
        void mounthShow();

    };
#endif // !CALENDAR_H_

Так выглядит .cpp-файл определения класса (ничего трудного)

#include "calendar.hpp"
#include <iostream>
#include <string>

using namespace std;


    MounthCalendar::MounthCalendar(){
        m_MounthName = "None";
        m_days = 1;
        m_DaysGrid *DaysGrid = new m_DaysGrid[m_days];

        for (int i = 0; i < m_days; i++)
        {
            DaysGrid[i].ms_centerName = "null";
            DaysGrid[i].ms_date = i;
            DaysGrid[i].ms_weekend = 0;

        }
    }

    MounthCalendar::MounthCalendar(const string & mounthName, unsigned short int days){
        m_MounthName = mounthName;
        m_days = days;
        m_DaysGrid *DaysGrid = new m_DaysGrid[m_days];

        for (int i = 0; i < m_days; i++)
        {
            DaysGrid[i].ms_centerName = "null";
            DaysGrid[i].ms_date = i;
            DaysGrid[i].ms_weekend = 0;

        }

    }

    MounthCalendar::~MounthCalendar(){      
    }



void MounthCalendar::mounthShow(){

    cout << "MounthName: " << m_MounthName << endl;
    cout << "Days per mounth = " << m_days << endl;

    for (int i = 0; i < m_days; i++){
        cout << "Date: " << DaysGrid[i].ms_date <<" ";
        DaysGrid[i].ms_weekend == true ? cout << "true" : cout << "false";
        cout << "Center name = " << DaysGrid[i].ms_centerName << endl;
    }

}

И, собственно, сам main

#include <iostream>
#include <string>
#include "calendar.hpp"
using namespace std;

int main(int argc, const char** argv) {

    MounthCalendar April = MounthCalendar("March", 10);
    April.mounthShow();

    return 0;

}

И вроде бы все работает, но фиг там.

Вывод при использовании произвольного конструктора

Ошибка сегментации. Опережаю вопрос: почему нельзя, к примеру, объявить такой динамический массив в конструкторе? Потому что такой массив будет не виден за его пределами. Если я все правильно понял. Предлагаю закрыть это вопрос раз и навсегда, пример специально приторно простой, дабы каждый смог въехать. Спасибо всем, кто откликнется.


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

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

Просто замените эти две строки в конструкторах

m_DaysGrid *DaysGrid = new m_DaysGrid[m_days];

на правильные

DaysGrid = new m_DaysGrid[m_days];

Ну и желательно в деструкторе добавить удаление через delete.

MounthCalendar::~MounthCalendar(){
    delete[] DaysGrid;
}

Что происходит? Вы создаете в конструкторе локальную переменную, в которой сохраняете свой массив с данными. А в mounthShow обращаетесь к переменной-члену класса, которая не знает о этом. То, что у них имена совпадают, ещё не значит, что они хранят одно и тоже.

p.s. Вот так

} *DaysGrid = new m_DaysGrid[m_days]; //Решил, что так правильней, ошибок компиляции нет.

хоть оно и компилируется, лучше не писать. Или чистить аккуратно память.

p.s.s. А лучше использовать std::vector вместо динамического выделения памяти. Сэкономит кучу нервов и время.

→ Ссылка