user13679586
user13679586

Reputation:

I want to allocate memory to function pointer

I have 2 functions that have same parameters and return type. Like

int fun1(int a){
  return a+1;
}

int fun2(int a){
  return a+2;
}

I made a funtion pointer int(*funptr)(int).

And I want to use malloc and make funptr[0] to point fun1, and funptr[1] to point fun2.

So I tried like

int(*funptr)(int)=(int*)malloc(2*sizeof(funptr));  

but it doesn't work. What can I do?

Upvotes: 2

Views: 914

Answers (4)

0___________
0___________

Reputation: 67476

You cant index function pointers. You need to declare the array of function pointers or pointer to pointer to function

int fun1(int a){
    return printf("%s\n",__FUNCTION__);
}
int fun2(int a){
    return printf("%s\n",__FUNCTION__);
}

typedef int func(int);

int main()
{
    func *farr[2];

    farr[0] = fun1;
    farr[1] = fun2;

    for(int x = 0; x < 20; x++)
    {
        farr[(rand() & 1)](1);
    }
}

or everything together

int fun1(int a){
    return printf("%s\n",__FUNCTION__);
}
int fun2(int a){
    return printf("%s\n",__FUNCTION__);
}

int fun3(int a){
    return printf("%s\n",__FUNCTION__);
}

int fun4(int a){
    return printf("%s\n",__FUNCTION__);
}

typedef int func(int);
typedef int (*fa[2])(int);

int main()
{
    func *farr[2];
    func **fapp = malloc(2*sizeof(*fapp));
    fa *fap = malloc(2 * sizeof(*fap));

    farr[0] = fun1;
    farr[1] = fun2;

    fapp[0] = fun1;
    fapp[1] = fun2;

    fap[0][0] = fun1;
    fap[0][1] = fun2;
    fap[1][0] = fun3;
    fap[1][1] = fun4;

    for(int x = 0; x < 20; x++)
    {
        farr[(rand() & 1)](1);
    }

    printf("------------------------------\n");

    for(int x = 0; x < 20; x++)
    {
        int x = rand() % 4;
        fap[x / 2][x & 1](1);
    }

    printf("------------------------------\n");

    for(int x = 0; x < 20; x++)
    {
        fapp[rand() & 1](1);
    }
}

https://godbolt.org/z/OSFGSp

Upvotes: 0

klutt
klutt

Reputation: 31377

Just do a simple array of function pointers.

int (*f)[2](int); 
f[0] = fun1;
f[1] = fun2;

Use typedefs if you think the declaration syntax is tricky.

Another thing, if you want you can use malloc instead if you want, but Don't cast malloc

Here you actually made a mistake. You should have casted to a function pointer and not an integer pointer. Well, you should not have casted at all. Here it what it should have looked like:

int (**f)(int) = malloc(2 * sizeof *f); 
if(!f) { /* Handle error */ } 
f[0] = fun1;
f[1] = fun2;
free(f);

Upvotes: 1

Lundin
Lundin

Reputation: 213810

You almost certainly do not want to allocate an array of functions pointers dynamically. Bad idea.

If you insist, then first of you must realize that malloc always returns an object pointer of type void*, which is incompatible with function pointers. As is your current senseless cast to int*. So you need to go to some well-defined middle ground in between function pointers and object pointers, like a uintptr_t integer.

It is getting tedious to over and over again tell people to use typedef when working with function pointers, so I'm not gonna do that yet again. This will be messy even with such a typedef.

Given typedef int func_t (int);, an array of function pointers is func_t* arr[2];. However, since you use malloc, you actually need to use a pointer to such an array: func_t* (*funptr)[2].

The malloc call will be malloc(sizeof(func_t*[2])). However, as mentioned you need to cast the result into something that isn't an object pointer and pray that it's still portable: (uintptr_t)malloc(sizeof(func_t*[2]));. This is the least questionable I can come up with.

Then you must cast that one to a pointer to array of function pointer type. (func_t*(*)[2]).

The abomination end result:

typedef int func_t (int);

int main (void)
{
  func_t* (*funptr)[2] = (func_t*(*)[2]) (uintptr_t)malloc(sizeof(func_t*[2]));

  (*funptr)[0](1);
  (*funptr)[1](1);

  free(funptr);
}

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134326

What I understand is you need an array of function pointers. Change

 int(*funptr)(int)

to

int  (*funptr)[2] (int)

and use funptr[0] = fun1; and funptr[1] = fun2;

Alternatively, if you must use allocated memory, you can use a pointer to function pointer

int (**funptr)(int);

and then use accordingly. For ease of use, do use typedef.

 typedef int(*funptr)(int);

 funptr * fp;
 fp = malloc(2* sizeof*fp);
 fp[0] = fun1;
 fp[1] = fun2;

Upvotes: 3

Related Questions