Ответ 1
-
Во-первых, "воздействие" заключается в том, что ваш первый метод нарушен. Он не будет работать с указателем
int **
.Чтобы выделить 2D-массив одним выстрелом, когда вы пытаетесь сделать это в своем первом методе, вам фактически необходимо выделить 1D-массив достаточного размера
int *arr = malloc( row * column * sizeof *arr ); // Note: `int *`, not `int **`
и выполнить доступ путем ручного пересчета индекса, например. вместо
arr[i][j]
вам нужно сделатьarr[i * column + j]
.Попытка сохранить выделенный указатель в
int **arr
, а затем получить доступ к вашему массиву, посколькуarr[i][j]
просто приведет к сбоям. -
Во-вторых, ваш второй метод в порядке. Просто во втором методе вам не требуется выделять память второго уровня несколькими независимыми вызовами
malloc
. Вы можете выделить всю память второго уровня за один снимокint **arr = malloc( row * sizeof *arr ); int *arr_data = malloc( row * column * sizeof *arr_data );
а затем просто распределите эту предварительно выделенную память второго уровня между строками
for (i = 0; i < row; i++) arr[i] = arr_data + i * column;
(Разумеется, вы можете выделять строки независимо друг от друга, если хотите, также будет работать. Причина, по которой я хотел выделить их одним выстрелом, - это лучше проиллюстрировать сходство между первым и вторым подходами, ниже.)
Теперь, взглянув на эти два метода, вы можете легко увидеть, что оба они по существу делают одно и то же. Единственное различие заключается в том, что в первом методе вы находите начало строки "на лету", вычисляя arr + i * column
каждый раз (обратите внимание, что arr[i * column + j]
эквивалентно (arr + i * column)[j]
). Во втором методе вы заранее предварительно вычисляете все начальные строки, используя ту же формулу arr_data + i * column
и сохраняете их для дальнейшего использования в отдельном массиве "индекс строки" arr
.
Таким образом, это в основном сводится к компромиссу между использованием памяти (первый метод требует меньше памяти) и скоростью (второй метод потенциально, но не обязательно, быстрее). В то же время второй метод поддерживает "естественный" синтаксис для доступа к двумерному массиву - arr[i][j]
, в то время как в первом методе вы должны использовать более сложный синтаксис доступа 1D с пересчетом индекса.