How to pass array of function pointers to another function - c++

I have got 2 functions:
char* odwroc(char* nap, int n)
char* male(char* nap, int n)
I have defined a pointer to that kind functions
typedef char*(*pointerToFunction )( char*, int );
then in used that definition in main:
pointerToFunction ptr1 = odwroc;
pointerToFunction ptr2 = male;
but now I have to create a function which as a first parameter gets array of that pointers to function and I am stuck. I don't know how to define array of pointers to function and how the modyfikuj parameter list should look like.
void modyfikuj(char* pointerToFunction *pointerArray, int length, char* nap2, int n){
}

Try this:
pointerToFunction mojefunkcje[] = { odwroc, male};
modyfikuj( mojefunkcje, ...); // pass the array fo modyfikuj()
void modyfikuj( pointerToFunction* funtab, ...)
{
funtab[0]( string, liczba); // call odwroc( string, liczba)
funtab[1]( string, liczba); // call male( string, liczba)
}

Even though the above answer make sense, use of containers such as std::vector will give you more control when passing an array of similar type such as a pointer to a function. Please try below code snippet.
#include "vector"
using namespace std;
typedef char*(*pointerToFunction )( char*, int );
typedef vector<pointerToFunction> FUNCTION_VECTOR;
bool modyfikuj( FUNCTION_VECTOR& vecFunctionVector )
{
// The below checking ensures the vector does contain at least one function pointer to be called.
if( vecFunctionVector.size() <= 0 )
{
return false;
}
// You can have any number of function pointers to be passed and get it executed, one by one.
FUNCTION_VECTOR::iterator itrFunction = vecFunctionVector.begin();
FUNCTION_VECTOR::const_iterator itrFunEnd = vecFunctionVector.end();
char* cszResult = 0;
for( ; itrFunEnd != itrFunction; ++itrFunction )
{
cszResult = 0;
// Here goes the function call!
cszResult = (*itrFunEnd)( "Hello", 1 );
// Check cszResult for any result.
}
return true;
}
char* odwroc(char* nap, int n); // You will define this function somewhere else.
char* male(char* nap, int n); // You will define this function somewhere else.
int main()
{
FUNCTION_VECTOR vecFunctions;
// You can push as many function pointers as you wish.
vecFunctions.push_back( odwroc );
vecFunctions.push_back( male );
modyfikuj( vecFunctions );
return 0;
}

Related

Returning a array from a void * argument in a function

I have a variadic function that takes at least 3 arguments, and is of the form
foo(void* ret_val, int mode, int num_params, ...)
The general use of the variadic function foo() can involve returning different data types as well as an arbitrary number of input arguments that can have various data types, but I am unable to find a way of returning an array.
How can I return an array?
The function definition is that the first argument returns an arbitrary type depending on the function invoked by foo(), mode is the mode of operation, and num_params is the number of additional input parameters, which can be zero. There is a switch statement inside foo() which depending on mode, can invoke one or more functions, and can return a value of an arbitrary type.
As a simplified example, suppose I have the following 3 functions that are invoked by foo():
void bar1(int i, int, j) {
// Do some calculations but return nothing.
}
int bar2() {
// Do some calculations and return a value.
}
int* bar(3) {
// Do some calculations with an array and return it.
}
Then in foo() I can have the following code:
foo(void* ret_val, int mode, int num_params, ...) {
va_list args;
va_start(args, num_params);
switch (mode) {
case 1: {
int a = va_arg(args, int);
int b = va_arg(args, int);
bar1(a, b);
}
break;
case 2: {
int val = bar1();
*(int*)ret_val = val;
}
break;
case 3: {
int* p = new int[10];
p = bar3();
// Add a loop to test out that the array has been read from bar3(), which works.
*(int*)ret_val = *p; // <== This is where the problem is.
}
break;
}
va_end(args);
}
Then in the main program I can invoke foo() in the following way:
int x;
foo(&x, 1, 2, 10, 20); // Call bar1()
foo(&x, 2, 0); // Call bar2()
printf("%d\n", x);
int xd[10]; // Declare and initialize xd.
for (int i = 0; i < 10; i++) {
xd[i] = 0;
}
foo(xd, 3, 0) // Call bar3()
for (int i = 0; i < 10; i++) {
printf("%d %d\n", i, xd[i]);
}
I put in the calls for bar1() and bar2() for context, and they work. For bar1() two ints are provided, but nothing is returned, and a dummy output argument has to be provided. For bar2() no input values are given, but an output int is returned, which is cast to star(int star) which works and is returned correctly.
However, for bar3() internally I generate a 10 element array as a test, which is correctly returned inside foo() from the print statement, but I am unable to return the array to main(). I have fiddled around with various statements involving pointers, but either a list of zeros is returned if the array is initialized, or garbage if it is not.
How can I return an array correctly?
In this call
foo(xd, 3, 0)
the array designator xd is converted to pointer to its first element and the function deals with a copy of this value.
Within the function this statement
*(int*)ret_val = *p;
just changes the first element of the array xd with the value of the first element of the array pointed to by the pointer p.
Arrays do not have the copy assignment operator. You can not assign one array to another as for example
int a[10] = { /*...*/ };
int b[10] = { /*...*/ };
a = b;
So this code snippet
int* p = new int[10];
p = bar3();
// Add a loop to test out that the array has been read from bar3(), which works.
*(int*)ret_val = *p;
does not make a sense. Moreover it seems there is a memory leak because at first the pointer p was assigned with the address of the allocated memory
int* p = new int[10];
and then reassigned with the value returned by the function bar3.
p = bar3();
You can write foo as shown below (in C, as this question was originally tagged). Comments show how to think about ret_val. Note that the interface for bar3 has been changed.
/* ret_val is a pointer to some type T, a "T *", that has been converted to
"void *". To use it, we convert it back to its original type "T *".
*/
foo(void *ret_val, int mode, int num_params, ...)
{
va_list args;
va_start(args, num_params);
switch (mode)
{
case 1:
{
// T is void. Nothing is returned via ret_val.
int a = va_arg(args, int);
int b = va_arg(args, int);
bar1(a, b);
}
break;
case 2:
{
/* We will return an int, so T is an int, and we convert ret_val
back to "int *".
*/
int val = bar1();
// Return val.
* (int *) ret_val = val;
}
break;
case 3:
{
/* We will return a pointer to an int, so T is an "int *", and
we convert ret_val back to "int **".
int *p = malloc(10 * sizeof p);
if (!p)
{
fprintf(stderr, "Error, memory allocation failed.\n");
exit(EXIT_FAILURE);
}
bar3(p);
// Return p.
* (int **) ret_val = p;
}
break;
}
va_end(args);
}
Then, for case 3, you can call foo with:
int *xd;
foo(&xd, 3, 0);

Examples about function pointer and callback function definition

I'm learning about callback function in C++ and have some problems in understanding the initialization of a callback function such as
typedef void (CALLBACK *name)(int,int);
I think it looks very similar to the declaration of function pointer like this:
typedef void (*name)(int,int);
I have a simple example about how to call a function inside another function using the declaration of function pointer. The example converts a string to int and compare with anoter int. Then tells which one is bigger:
#include <stdio.h>
#include <stdlib.h>
int StrToInt(char* inputchar) //converting function
{
int outputint;
outputint = atoi(inputchar);
return outputint;
}
typedef int(*p)(char*); //declare function pointer
void IntCompare(p FuncP, char* inputchar, int b) //comparing function
{
int a;
a = FuncP(inputchar); //call converting function using function pointer
if (a<b)
{
printf("%d is bigger\n", b);
}
else
{
printf("%d is bigger\n", a);
}
}
void main()
{
char* StrNum = "1234";
p FuncP; //creat a function pointer
FuncP = StrToInt; //point to converting function
IntCompare(FuncP, StrNum, 21);
}
What I'm asking is:
Could somebody give me a similar example about how to use typedef void (CALLBACK *name)(int,int);? Please help me understand when and how to use it. Thank you for your attention.
CALLBACK is macro. It relates to callback functions but it's not the same. You can start looking at implementation of callback functions in C.
qsort for example uses this technique. qsort is a single function which can sort any array. But you have to tell qsort how to compare different data types. That's done by passing a function pointer to qsort.
int compare_int(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int compare_string(const void * a, const void * b)
{
const char *pa = *(const char**)a;
const char *pb = *(const char**)b;
return strcmp(pa, pb);
}
int main ()
{
int int_array[] = { 3, 2, 1 };
int count = sizeof(int_array) / sizeof(int);
qsort(int_array, count, sizeof(int), compare_int);
const char *string_array[] = { "234","123","456" };
count = sizeof(string_array) / sizeof(char*);
qsort(string_array, count, sizeof(char*), compare_string);
return 0;
}
Of course in C++ we use std::sort, which uses templates instead.
But we still need to pass functions in C++. See for example, the implementation of for_each
template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
for (; first != last; ++first) {
f(*first);
}
return f;
}
Usage:
std::vector<int> nums{ 3, 4, 2, 8, 15, 267 };
auto print = [](const int& n) { std::cout << " " << n; };
std::for_each(nums.begin(), nums.end(), print);
std::cout << '\n';

Passing an array to a function which accepts double pointer in arg-list

I want to pass newly defined array bool myArr[] = { false, false, true }; to below existing function.
void fun(bool** pArr, int idx)
{
if(NULL == *pArr)
return;
(*pArr)[idx] = false;
...
...
return;
}
I am not allowed to change anything in subroutine fun and I want to invoke the function by using the identifier myArr. When I try fun(&myArr, 2); I get below compilation error.
no matching function for call to fun(bool (*)[3], int)
candidates are: void fun(bool**, int)
One way I can think of is as below
bool* ptr = myArr;
fun(&ptr, 2);
But it looks dirty to me, please suggest a way to invoke fun my using the myArr
Functions that want a pointer to a pointer typically expect a jagged array. You can construct an array of arrays with a single element myArray, and pass that array to your function, like this:
bool *arrayOfPtrs[] = { myArray };
fun(arrayOfPtrs, 2);
This reads slightly better than your pointer solution, because creating an array of pointers eliminates the question of why you are creating a pointer to a pointer (demo).
This functions expects a pointer to a bool*, so the only way to call it is to have an actual bool* object somewhere. Your solution is the only one.
If you want to avoid using a hack every time you call the function you can simply write a wrapper function:
void fun(bool** pArr, int idx)
{
if(NULL == *pArr)
return;
(*pArr)[idx] = false;
}
void super_fun(bool* pArr, int idx)
{
fun(&pArr, idx);
}
int main()
{
bool myArr[] = { false, false, true };
super_fun(myArr, 2);
}
I would do a little differently. I Think this is a bit cleaner:
void fun2(bool * pArr, int idx)
{
*(pArr + idx) = true;
return;
}
int main(int argc, _TCHAR* argv[])
{
bool myArr[] = { false, false, true };
fun2(myArr, 1);
return 0;
}
Now I was playing with this in my c++14 and it didn't let me directly access the elements with an indexer. Maybe that changed at some point? But I thought this is reasonable.
Edit, this is really better:
void fun3(bool pArr[], int idx)
{
if (NULL == *pArr)
return;
pArr[idx] = false;
return;
}

How to define pointer to pointer to function and how to use it in C++?

My question is how to translate the following example? Is this a function, that returns int pointer?
int* (*function)(int, (int (*k)(int *)));
And can I can't write program that use it?
Thanks in advance!
It is a function-pointer
The function returns a pointer to an int
The function's first arg is an int
The function's second arg is a function-pointer k
k returns an int
k takes a pointer to an int as argument
Sure you can use that in your program. It is not too unusual. There are much worse declarations i have seen.
I renamed your "function" to "F" for clarity. Then you can write:
int* (*F)(int, int (*kFunc)(int *) );
Alternative:
typedef int (*kFunc)(int *);
int* (*F)(int, kFunc);
There are a lot of ways to use pointer to a function, may be a pattern such as Factory could take advantage of the function pointer to create new objects.( Look here : http://www.codeproject.com/Articles/3734/Different-ways-of-implementing-factories)
May be this piece of code could help you and give ideas of how powerfull can be working with function pointers.
#include <stdio.h>
#include <stdlib.h>
#include <map>
// Define the func ptrs
typedef void (*TFunc)(const char *, int);
typedef int (*TFunc2)(int);
int return_value(int i)
{
return i * 5;
}
void a( const char *name, int i )
{
printf ("a->%s %d\n\n", name, i);
}
void b( const char *name, int i)
{
printf ("b->%s %d\n\n", name, i);
}
struct test
{
const char *name;
int i;
TFunc func;
};
static test test_array[2] =
{
{ "a", 0, a },
{ "b", 1, b },
};
int main(int argc, char **argv, char** envp)
{
// Check the simple case, pointer to a function
TFunc fnc = a;
TFunc2 fnc2 = return_value;
fnc("blabla", 5);
fnc = b;
fnc("hello!", 55);
printf ("%d\n\n",fnc2(5));
//Check arrays of structs when there is a pointer to a fnc
test_array[0].func(test_array[0].name, test_array[0].i);
test_array[1].func(test_array[1].name, test_array[1].i);
//Handle a map of functions( This could be a little implementation of a factory )
typedef std::map<int, TFunc > myMap;
myMap lMap;
lMap.insert(std::make_pair(5, a));
lMap.insert(std::make_pair(2, b));
if( lMap.find( 5 ) != lMap.end() )
{
lMap[5]("hello map 5", 1);
}
myMap::iterator lItFind = lMap.find(2);
if( lItFind != lMap.end() )
{
lItFind->second("hello map 2", 2);
}
return(0);
}
I hope that this helps you.
You should remove extra parentheses, this is correct version:
int* (*function)(int, int (*k)(int *));
explanation (using right-left rule):
int* (*fn)(int, int (*k)(int *));
fn : fn is a
(*fn) : pointer
(*fn)(int, int (*k)(int *)) : to a function taking as arguments
- an int and
- function pointer
which takes a pointer to int
and returns int
int* (*fn)(int, int (*k)(int *)) : and returns a pointer to int
below is a short example on how to use it, also you ask for How to define pointer to pointer to function so below this is also included.
http://coliru.stacked-crooked.com/a/d05200cf5f6397b8
#include <iostream>
int bar(int*) {
std::cout << "inside bar\n";
return 0;
}
int* foo(int, int (*k)(int *)) {
std::cout << "inside foo\n";
k(nullptr);
return nullptr;
}
int main() {
int* (*function)(int, int (*k)(int *));
function = foo;
function(0, bar);
// Now, as you asked for, a pointer to pointer to above function
decltype(function) *pff;
pff = &function;
(*pff)(0, bar);
}

Increment the value of a pointer when sent as a parameter

I am stuck in the following pointer problem:
Say you have a function:
void Function (unsigned char *ubPointer)
{
ubPointer++;
}
int main (void)
{
unsigned char *PointerX;
Function( PointerX );
}
What I want is that the ++ is reflected in PointerX, without declaring it as a global variable.
Thank you very much.
In C++, pass your pointer by reference (and don't forget to specify a return type for your function):
void Function (unsigned char*& ubPointer)
// ^
{
ubPointer++;
}
This won't require any further change in the calling code. When returning from the function, the side-effects on ubPointer will be visible to the caller.
In C, you can achieve the equivalent result by passing a pointer to your pointer:
void Function (unsigned char** ubPointer)
// ^
{
(*ubPointer)++;
// ^^^^^^^^^^^^
}
This will require you to change the way you are calling your function:
int main()
{
unsigned char* p;
Function(&p);
// ^
}
Or, if you want to do it C-style
void Function (unsigned char **ubPointer)
{
(*ubPointer)++;
}
because
Function (unsigned char **ubPointer)
{
ubPointer++;
}
would be increasing the address pointed to.
void Function (unsigned char *ubPointer)
{
(*ubPointer)++;
}
int main (void)
{
unsigned char *PointerX;
Function( PointerX );
}
This is the correction