Вопрос: Как динамически выделить память для многомерного массива?

Ответ:

Лучше всего выделить память для массива указателей, а затем инициализировать каждый указатель так, чтобы он указывал на динамически создаваемую строку. Вот пример для двумерного массива:
int **array1 = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
  array1[i] = (int *)malloc(ncolumns * sizeof(int));

(В "реальной" программе, malloc должна быть правильно объявлена, а каждое возвращаемое malloc значение — проверено.)

Можно поддерживать монолитность массива, (одновременно затрудняя последующий перенос в другое место памяти отдельных строк), с помощью явно заданных арифметических действий с указателями:
int **array2 = (int **)malloc(nrows * sizeof(int *));
array2[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
for(i   = 1; i < nrows; i++)
  array2[i] = array2[0] + i * ncolumns;

В любом случае доступ к элементам динамически задаваемого массива может быть произведен с помощью обычной индексации: array[i][j].

Если двойная косвенная адресация, присутствующая в приведенных выше примерах, Вас по каким-то причинам не устраивает, можно имитировать двумерный массив с помощью динамически задаваемого одномерного массива:
int *array3 = (int *)malloc(nrows * ncolumns * sizeof(int));

Теперь, однако, операции индексирования нужно выполнять вручную, осуществляя доступ к элементу i,j с помощью array3[i*ncolumns+j].
(Реальные вычисления можно скрыть в макросе, однако вызов макроса требует круглых скобок и запятых, которые не выглядят в точности так, как индексы многомерного массива).

Наконец, можно использовать указатели на массивы:
int (*array4)[NCOLUMNS] =
       (int*)[NCOLUMNS])malloc(nrows * sizeof(*array4));

но синтакс становится устрашающим, и "всего лишь" одно измерение должно быть известно во время компиляции.

Пользуясь описанными приемами, необходимо освобождать память, занимаемую массивами (это может проходить в несколько шагов; см. вопрос 3.9), когда они больше не нужны, и не следует смешивать динамически создаваемые массивы с обычными, статическими (cм. вопрос 2.15 ниже, а также вопрос 2.10).
Автор: Кодт    Оценить