Страницы

Поиск по вопросам

четверг, 8 ноября 2018 г.

Как надо выделять память

Суть вопроса. Есть класс:
class a { private: int **something;
public: a(); ~a(); };
Собственно, как правильно выделять память под двумерный динамический массив? А точнее, где? Некоторые источники указывают на то, что надо не «перегружать» конструктор лишними вычислениями и выделением памяти, а засунуть все в другой метод.
a(){something = nullptr;} void doMemory(){ /* выделение памяти */ } ~a(){if(something != nullptr) /* высвобождаем */);}
По моим соображениям "засунуть все в другой метод" интересен, если мы создаем больше объекты и они просто лежат в памяти и ждут своего часа, а когда этот час настает, мы берем объект выделяем под него память и сразу работаем с ним, и он дальше лежит ждет своего часа.


Ответ

Когда выделять?
Выделять память нужно в конструкторе, освобождать - в деструкторе. Это - реализация одной из важнейших концепций C++ - RAII (получение ресурса есть инициализация). Если ее нарушить, программа будет либо ненадежной, либо потребуется в каждом методе следить - выделена ли память.
Выделять крупный блок или матрицу указателей?
Зависит от размеров и от того, что нужно в дальнейшем с этой матрицей делать.
Если программа работает с гигабайтами данных, и работает не один раз, а в несколько проходов (выделяя и освобождая память между ними), может оказаться, что адресное пространство сильно фрагментировано, и такого длинного куска, как вам нужно - просто нет.
Для 64 бит это не так актуально, но есть на свете и 32 битные системы (в мобильниках и так далее).
Если этим данным предстоит параллельная обработка на многоядерной системе с NUMA, а вы выделили память крупным блоком, эта самая NUMA вставит вам палки в колеса, когда процессоры полезут не в свои банки памяти за данными - при выделении построчно вероятность такого будет меньше.
Итого: Каждый сценарий обработки данных требует индивидуального выбора способа их хранения.

Комментариев нет:

Отправить комментарий