Прежде всего, зачем выделять динамическую память?
Если вы используете обычный массив, все становится немного проще:
int (*funcs[])(int, int) = {
comp_int,
comp_int_abs,
comp_int_length,
comp_int_digits_sum,
};
Если вы хотите использовать динамическое размещение, есть несколько вещей, на которые стоит обратить внимание.
int (**funcs)(int, int) = malloc(4 * sizeof *funcs);
Сначала нам нужно выделить правильное количество памяти. Умножая на размер разыменованного указателя, нам не нужно беспокоиться о типе элемента динамического массива. (Но если бы мы хотели написать тип вручную, это было бы sizeof (int (*)(int, int))
, а не sizeof (int)
, как в вашем коде; элементы нашего массива являются указателями на функции, а не целыми числами.)
Затем мы проверяем наличие ошибки выделения:
if (!funcs) {
Примечание. Мы проверяем сам указатель (funcs
), а не первый элемент динамического массива (который может не существовать!), Как в вашем коде (*funcs
). Если malloc
завершится ошибкой и вернет NULL
, !*funcs
попытается разыменовать нулевой указатель, что, скорее всего, приведет к аварийному завершению вашей программы.
fprintf(stderr, "Failed to allocate memory\n");
Сообщения об ошибках идут на stderr
, а не stdout
. Строки заканчиваются на '\n'
.
return 8;
}
Поскольку у нас нет реального массива, мы не можем использовать синтаксис инициализации. В частности, = {
недопустимо в выражениях присваивания.
Самое простое решение - назначить элементы вручную:
funcs[0] = comp_int;
funcs[1] = comp_int_abs;
funcs[2] = comp_int_length;
funcs[3] = comp_int_digits_sum;
Это немного подвержено ошибкам, потому что мы должны указывать каждый индекс вручную. Однако мы можем объединить это с кодом «нормального массива» сверху:
int (*const funcs_init[])(int, int) = {
comp_int,
comp_int_abs,
comp_int_length,
comp_int_digits_sum,
};
int (**funcs)(int, int) = malloc(sizeof funcs_init);
if (!funcs) { ... }
memcpy(funcs, funcs_init, sizeof funcs_init);
Мы просто инициализируем наш массив как обычно (здесь он называется funcs_init
), затем копируем содержимое в нашу динамически выделенную память, используя memcpy
.