Выделение памяти указателю на функцию

У меня есть функция, чтобы добавить два номера и вернуться (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));
}

В большинстве систем все указатели имеют одинаковый размер.

Barmar 13.12.2020 19:00

В C имя функции совпадает с указателем на функцию. Попробуйте printf("sizeof fnc=%ld, sizeof fnc pointer=%ld\n", sizeof(add), sizeof(*add));

Frankie_C 13.12.2020 19:01

Попытка применить sizeof к типу функции является поведением undefined согласно 6.5.3.4 спецификации C. Таким образом, вы можете получить тот же размер, что и указатель на функцию, или вы можете получить ошибку, или что-то еще.

Chris Dodd 13.12.2020 20:56

@ChrisDodd, ты прав. Это УБ. Мой пример не корректен. Но концепция преобразования указателя функции из «типа, возвращаемого функцией» в «указатель на тип, возвращаемый функцией», верна, как указано в §6.3.2.1 Lvalues, массивы и указатели функций, запятая 4: тип функции. За исключением случаев, когда это операнд оператора sizeof или унарного оператора &, указатель функции с типом «тип, возвращающий функцию», преобразуется в выражение, имеющее тип «указатель на тип, возвращающий функцию».>. Он также обеспечивает соблюдение UB для sizeof.

Frankie_C 13.12.2020 21:53

Спасибо за ответ на мой запрос. У меня есть другая мысль... когда мы делаем sizeof() для предопределенного указателя типа данных, такого как int p или char *c, мы делаем sizeof(*p), но когда мы используем сам тип данных, мы помещаем после этого символ разыменования, например как sizeof(int *) или то же самое в случае пользовательского типа данных, такого как sizeof(add_2nos) в приведенном выше коде. Почему так?? Может кто подскажет...?

Niranjan Das 15.12.2020 14:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
422
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Указатель определяет адрес памяти. Проще всего объяснить это на следующем примере:

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

M.M 14.12.2020 05:07

Этот

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.

Другие вопросы по теме