Хорошо ... здесь у вас есть, в основном, указатель-указатель, а именно адрес адреса. Вы можете использовать этот тип переменной при работе с массивами.
Первые две строки вашего кода эквивалентны:
int* a[5]; // Declaration of an array of 5 integer pointers (a[0] till a[4]).
«Чистый» код C не использует переменную для размера массива, поэтому вы используете malloc, когда хотите динамически редактировать размер массива.
То есть, если в своем коде вы не собираетесь изменять размер своих массивов, вы используете очень сложный способ достижения очень простой цели. Вы можете просто набрать:
int a[5][3];
Но если вы не знаете размер вашего массива, вы должны использовать malloc (а затем и free). Что вы делаете, в основном, это:
- Объявление массива массива;
- Выделение памяти для x числа POINTER для целочисленных массивов;
- Для каждого из этих указателей, выделяя память для y целых чисел.
Теперь, когда вы сделали это, вы можете нормально использовать свои массивы. Например:
a[1][0] = 1;
будет означать: в первом массиве [1] первая строка [0] равна 1.
Единственное отличие стандартного объявления, подобного приведенному выше, без использования malloc состоит в том, что, поскольку вы распределили память, вам придется ее освободить. Вот почему вы не хотите потерять свою переменную **. В конце вашей функции будет уничтожена переменная указатель-указатель, но не выделенная вами память.