динамическое выделение/освобождение 2D и 3D массивов

В более новых версиях PHP E_ALL включает больше классов ошибок. Начиная с PHP 5.3 E_ALL включает все кроме E_STRICT. В PHP 6 это будет alledgedly включать даже это. Это - хорошая подсказка: лучше видеть больше сообщений об ошибках, а не меньше.

то, Что включено в E_ALL, документируется в , PHP предопределил константы страница в руководстве онлайн.

Лично, я думаю, что все так очень при использовании E_STRICT. Не имеет значения это, конечно, не причинит Вам боль, тем более, что это может препятствовать тому, чтобы Вы писали сценарии, которые имеют маленький шанс получения прерванного будущие версии PHP. С другой стороны, в некоторых случаях строгие сообщения могут быть слишком шумными, возможно, особенно, если Вы спешите. Я предлагаю, чтобы Вы включили его по умолчанию и выключили его, когда это становится раздражающим.

11
задан Ankur 1 December 2009 в 06:30
поделиться

2 ответа

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

typedef struct {
  int a;
  int b;
  int* data;
} Int2d;

Int2d arr2d = { 2, 3 };
arr2d.data = malloc(arr2d.a * arr2d.b * sizeof *arr2d.data);

Теперь arr2d [r] [c] становится arr2d.data [r * arr2d.b + c] . Распределение осуществляется на расстоянии одного свободного (). В качестве бонуса вы обязательно всегда будете носить с собой размеры динамических массивов.

Экстраполяция в 3d:

typedef struct {
  int a;
  int b;
  int c;
  int* data;
} Int3d;

Int3d arr3d = { 2, 3, 4 };
arr3d.data = malloc(arr3d.a * arr3d.b * arr3d.c * sizeof *arr3d.data);

//arr3d[r][c][d]
// becomes:
arr3d.data[r * (arr3d.b * arr3d.c) + c * arr3d.c + d];

Вы должны инкапсулировать эти операции с индексами (и (де-) выделения в этом отношении) в отдельной функции или макрос.

(Имена для r, c и d могли бы быть лучше - я выбрал строку, столбец и глубину. Хотя a, b и c являются пределами их соответствующих измерений, вы можете предпочесть что-то вроде n1, n2, n3 там, или даже использовать для них массив.)

11
ответ дан 3 December 2019 в 07:38
поделиться

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

void deallocate3D(int*** arr3D,int l,int m)
{
    int i,j;

    for(i=0;i<l;i++)
    {
        for(int j=0;j<m;j++)
        {
                free(arr3D[i][j]);
        }
        free(arr3D[i]);
    }
    free(arr3D);
}

arr3D - указатель на указатель на указатель, поэтому arr3D [i] - указатель на указатель, а arr3D [i] [j] - просто указатель. Правильно сначала освободить самое низкое измерение в цикле, а затем подниматься по измерениям до тех пор, пока не будет освобожден сам arr3D.

Также более идиоматично неявно дать malloc sizeof указанного типа. Вместо:

  arr3D[i] = (int**)malloc(m * sizeof(int*));

Сделайте это:

  arr3D[i] = (int**)malloc(m * sizeof(*arr3D[i]));

И да, к таким динамически распределенным многомерным массивам можно получить доступ так же, как к статически распределенным многомерным массивам.

4
ответ дан 3 December 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: