У меня есть функция, чтобы добавить два номера и вернуться (a+b). Затем я создал указатель func на файл func. Хотите выделить память для массива этого указателя функции и получить к ним доступ. код ниже.
Мой вопрос находится в следующей строке с использованием malloc:
pp = (add_2nos*)malloc(5 * sizeof(add_2nos*))
sizeof(add_2nos*) и sizeof(add_2nos) не имеют значения при компиляции. Какая разница если есть?? Также, если необходимо приведение типов, когда я выделяю память того же типа...?
#include <stdio.h>
#include <stdlib.h>
int add(int a, int b) {
return (a+b);
}
typedef int (*add_2nos)(int, int);
int main() {
add_2nos *pp;
// Defining an array of pointers to function add and accessing them
pp = (add_2nos*)malloc(5 * sizeof(add_2nos*));
pp[0] = add;
pp[1] = add;
printf("\n\nAdding two nos -- (14, 15): %d ", pp1[0](14, 15));
printf("\nAdding two nos -- (16, 16): %d \n\n", pp1[1](16, 16));
}
В C имя функции совпадает с указателем на функцию. Попробуйте printf("sizeof fnc=%ld, sizeof fnc pointer=%ld\n", sizeof(add), sizeof(*add));
Попытка применить sizeof
к типу функции является поведением undefined согласно 6.5.3.4 спецификации C. Таким образом, вы можете получить тот же размер, что и указатель на функцию, или вы можете получить ошибку, или что-то еще.
@ChrisDodd, ты прав. Это УБ. Мой пример не корректен. Но концепция преобразования указателя функции из «типа, возвращаемого функцией» в «указатель на тип, возвращаемый функцией», верна, как указано в §6.3.2.1 Lvalues, массивы и указатели функций, запятая 4: тип функции. За исключением случаев, когда это операнд оператора sizeof или унарного оператора &, указатель функции с типом «тип, возвращающий функцию», преобразуется в выражение, имеющее тип «указатель на тип, возвращающий функцию».>. Он также обеспечивает соблюдение UB для sizeof
.
Спасибо за ответ на мой запрос. У меня есть другая мысль... когда мы делаем sizeof() для предопределенного указателя типа данных, такого как int p или char *c, мы делаем sizeof(*p), но когда мы используем сам тип данных, мы помещаем после этого символ разыменования, например как sizeof(int *) или то же самое в случае пользовательского типа данных, такого как sizeof(add_2nos) в приведенном выше коде. Почему так?? Может кто подскажет...?
Указатель определяет адрес памяти. Проще всего объяснить это на следующем примере:
printf("%ld\n",sizeof(unsigned char));
printf("%ld\n",sizeof(unsigned char *));
В первой строке печатается размер беззнакового char, который составляет 1 байт. Во второй строке размер указателя, хранящего информацию о том, где в памяти хранится unsigned char. Это может варьироваться между компиляторами/платформами. Например, на https://www.onlinegdb.com/online_c_compiler печатается размер 8 байт.
Это вызывает неопределенное поведение, %d
является неверным спецификатором формата для результата sizeof
Этот
pp = (add_2nos*)malloc(5 * sizeof(add_2nos*));
дает вам распределение на основе размера указателя на указатель функции. Вероятно, это то же самое, что и указатель на функцию, а может и нет.
pp = malloc(5 * sizeof(add_2nos));
или
pp = malloc(5 * sizeof *pp);
Вы указали typedef add_2nos
как имя типа для «указателя на функцию с определенной сигнатурой», поэтому для выделения массива таких указателей вы просто хотите использовать sizeof для него напрямую (без разыменования) или использовать sizeof для разыменования указатель массива.
sizeof(add_2nos*) и sizeof(add_2nos) не имеют значения при компиляции. Какая разница, если она есть?
add_2nos
это void (*)(int, int)
- это указатель на функцию.
add_2nos*
это void (**)(int, int)
- это указатель на указатель на функцию.
Поскольку в большинстве архитектур все указатели имеют одинаковый размер, включая указатели на функции и указатели на указатели, а malloc()
просто принимает число, это не имеет значения. В любом случае вы хотите выделить место для 5
указателей на функции (т.е. 5 * sizeof(add_2nos)
), а не для 5
указателей на указатели на функции.
Не думайте об этом и дайте компилятору разобраться: pp = malloc(5 * sizeof(*pp));
— распространенный шаблон.
Также, если необходимо приведение типов, когда я выделяю память того же типа...?
Смотрите мы приводим результат malloc к C.
В большинстве систем все указатели имеют одинаковый размер.