C ++ 2D массив данных в конструкторе - когда инициализировать и удалить? - PullRequest
0 голосов
/ 30 мая 2018

Этот вопрос может быть немного глупым, но я все еще довольно новичок в C ++, и я давно с ним что-то делал.

У меня есть класс с именем LEDBitmap, которыйдолжен содержать ширину, высоту и данные растрового изображения только с единицами и нулями.

В заголовочном файле у меня есть следующая структура:

struct MapData
{
  uint8_t width;
  uint8_t height;
  uint8_t[][] data;
};

А также следующий конструктор,Деструктор и переменная-член:

class LEDBitmap
{

  public:
    LEDBitmap(uint8_t width, uint8_t, height, uint8_t data[][]);
    LEDBitmap(uint8_t width, uint8_t, height);
    virtual ~LEDBitmap() {   };

  [...]

  private: //members
    MapData _map;
};

Теперь я хочу написать конструкторы и, возможно, деструктор, и пока у меня есть следующее для первого конструктора:

//initialize an empty bitmap with only zeros in it
LEDBitmap::LEDBitmap(uint8_t width, uint8_t, height) {
  _map.width = width;
  _map.height = height;
  _map.data = new uint8_t[width][height];
}

Будет ли эта реализация работать?(вероятно, нет) И стоит ли мне на самом деле реализовывать деструктор?

РЕДАКТИРОВАТЬ: скорректировал мой код в соответствии с предложением @ gsamaras._map раньше был *_ptr раньше.

РЕДАКТИРОВАТЬ: друг предложил использовать calloc() вместо.У меня при этом теперь есть:

LEDBitmap::LEDBitmap(uint8_t width, uint8_t height) {
  _map.width = width;
  _map.height = height;
  _map.data = calloc(width*height*(sizeof(uint8_t));
}

и

class LEDBitmap
{

  public:
    LEDBitmap(uint8_t width, uint8_t, height, uint8_t data[][]);
    LEDBitmap(uint8_t width, uint8_t, height);
    virtual ~LEDBitmap() {
      free(_map.data);
    };

  private: //members
    MapData _map;

};

1 Ответ

0 голосов
/ 30 мая 2018

Так как ptr является указателем, нет.Вы пытаетесь заполнить поля структуры, в которой даже не выделена память.Это вызывает неопределенное поведение .

  1. Сначала вы должны выделить память для структуры, а затем заполнить ее.
  2. Затем в деструкторе вы должен освободить эту память.

Помните, что когда используется new, то также необходимо использовать delete.В общем, вы хотите вызывать delete ровно столько раз, сколько было вызвано new.


Но зачем использовать указатель?Это кажется излишним в этом случае.И когда вы используете указатели без уважительной причины, вы делаете свой код подверженным ошибкам.

Вот несколько советов, которые вы можете выбрать вместо использования указателя (который не потребует от вас определения конструктора):

  • Используйте std::vector<uint8_t>, чтобы выполнить всю работу под капотом ( относится ), как заявил НатанОливер.
  • Используйте struct MapData в качестве члена данныхвместо указателя.Это имеет смысл в программировании ООП, если вы хотите, чтобы структура была повторно использована другим классом, например.
  • Если структура предназначена для использования только из этого класса, тогда рассмотрите возможность предоставления классу непосредственно полейструктур, как его элементов данных, а не самой структуры.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...