Суть вопроса. Есть класс:
class a
{
private:
int **something;
public:
a();
~a();
};
Собственно, как правильно выделять память под двумерный динамический массив? А точнее, где? Некоторые источники указывают на то, что надо не «перегружать» конструктор лишними вычислениями и выделением памяти, а засунуть все в другой метод.
a(){something = nullptr;}
void doMemory(){ /* выделение памяти */ }
~a(){if(something != nullptr) /* высвобождаем */);}
По моим соображениям "засунуть все в другой метод" интересен, если мы создаем больше объекты и они просто лежат в памяти и ждут своего часа, а когда этот час настает, мы берем объект выделяем под него память и сразу работаем с ним, и он дальше лежит ждет своего часа.
Ответ
Когда выделять?
Выделять память нужно в конструкторе, освобождать - в деструкторе. Это - реализация одной из важнейших концепций C++ - RAII (получение ресурса есть инициализация). Если ее нарушить, программа будет либо ненадежной, либо потребуется в каждом методе следить - выделена ли память.
Выделять крупный блок или матрицу указателей?
Зависит от размеров и от того, что нужно в дальнейшем с этой матрицей делать.
Если программа работает с гигабайтами данных, и работает не один раз, а в несколько проходов (выделяя и освобождая память между ними), может оказаться, что адресное пространство сильно фрагментировано, и такого длинного куска, как вам нужно - просто нет.
Для 64 бит это не так актуально, но есть на свете и 32 битные системы (в мобильниках и так далее).
Если этим данным предстоит параллельная обработка на многоядерной системе с NUMA, а вы выделили память крупным блоком, эта самая NUMA вставит вам палки в колеса, когда процессоры полезут не в свои банки памяти за данными - при выделении построчно вероятность такого будет меньше.
Итого:
Каждый сценарий обработки данных требует индивидуального выбора способа их хранения.
Комментариев нет:
Отправить комментарий