Как создать динамический массив структур в классе С++
Есть класс, в котором помимо прочих членов есть член-структура, которая должна из себя представлять массив структур. То есть, когда создаем объект - в нем помимо прочих переменных, есть динамический массив структур. Хидер выглядит так:
#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 шт):
Просто замените эти две строки в конструкторах
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 вместо динамического выделения памяти. Сэкономит кучу нервов и время.
