0
votes

I have a func to add two nos and return (a+b). Then I created a func pointer to the func. Want to allocate memory for an array of that function pointer and access them. code is below.

My question is on the following line using malloc:

pp = (add_2nos*)malloc(5 * sizeof(add_2nos*))

sizeof(add_2nos*) and sizeof(add_2nos) does not make any difference while compiling. What is the difference if there is any ?? Also if type casting is necessary while I am allocating memory of the same type...?

#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));
}
3
On most systems, all pointers are the same size. - Barmar
In C the function name is the same of a pointer to function. Try printf("sizeof fnc=%ld, sizeof fnc pointer=%ld\n", sizeof(add), sizeof(*add)); - Frankie_C
Trying to apply sizeof to a function type is undefined behavior, per 6.5.3.4 in the C spec. So you might get the same size as a function pointer or you might get an error, or anything else. - Chris Dodd
@ChrisDodd you're right. It is an UB. My example isn't correct. But the concept of function designator conversion from 'function returning type' to 'pointer to function returning type' is correct, as stated in §6.3.2.1 Lvalues, arrays, and function designators comma 4: <A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.>. It also enforce the UB for the sizeof. - Frankie_C
Thanks for responding to my query. I have another thought ... when we do sizeof() to a predefined data type pointer such as int p or char *c, we do sizeof(*p) but when we use the data type itself we place the dereference symbol afterwards such as sizeof(int *) or same in case of user defined data type such as sizeof(add_2nos) in the code above. Why it is like this way ?? Can someone point it out...? - Niranjan Das

3 Answers

2
votes

sizeof(add_2nos*) and sizeof(add_2nos) does not make any difference while compiling. What is the difference if there is any ?

add_2nos is void (*)(int, int) - it's a pointer to a function.

add_2nos* is a void (**)(int, int) - it's a pointer, to a pointer to a function.

Because on most architectures all pointers have the same size, including function pointers and pointers to pointers, and malloc() just takes a number, it doesn't make a difference. Anyway you want to allocate space for 5 function pointers (ie. 5 * sizeof(add_2nos)), not for 5 pointers to function pointers.

Don't think about it and let the compiler figure it out: pp = malloc(5 * sizeof(*pp)); is a common pattern.

Also if type casting is necessary while I am allocating memory of the same type...?

See do we cast the result of malloc in C.

1
votes

This

pp = (add_2nos*)malloc(5 * sizeof(add_2nos*));

is giving you an allocation based on the size of a pointer to a function pointer. That's probably the same as a function pointer, but maybe not.

pp = malloc(5 * sizeof(add_2nos));

or

pp = malloc(5 * sizeof *pp);

You've typedef's add_2nos to be a typename for "pointer to function with a particular signature", so to allocate an array of such pointers, you just want to use sizeof on it directly (no dereference), or use sizeof on the dereference of the array pointer.

0
votes

Pointer determines memory address. The easiest way to explain this is by this example:

printf("%ld\n",sizeof(unsigned char));
printf("%ld\n",sizeof(unsigned char *));

In the first line, the size of an unsigned char is printed, which is 1 byte. In the second line, the size of a pointer which keeps the information, where unsigned char is stored in the memory. This may vary between compilers/platforms. For example, on https://www.onlinegdb.com/online_c_compiler size of 8 bytes is printed.