Arrays and function pointers - c

How do pass an array of pointers to functions as a argument to a function? If the types of the functions are void and so is the pointer, how do you access the functions?
int main() {
void(*fun_ptr[])(void) = {fun1, fun2, fun3};
pickFun(fun_ptr);
return 0;
}
All 3 functions only print a message and are declared as void
void pickFun(void *function_ptr[])
{
int pick = 0;
while(pick != 0)
{
scanf("%i", &pick);
*(function_ptr + (pick - 1));
}
}
I can never get the function's printf statements to appear when a function is chosen. The program just loops and never prints the message contained in each function. Any suggestions or clues?

Function parameter void *function_ptr[] is of type pointer to pointer tovoid`. You need to change it to
void pickFun(void (*function_ptr[])(void));
Also note that, as others pointed out in comments, program never enters the loop body. Better to use do while loop here
void pickFun(void *function_ptr[])
{
do
{
scanf("%i", &pick);
//*(function_ptr + (pick - 1));
function_ptr[pick-1](); //Function call. pick should not be greater than 3
} while(pick != 0)
}

Also, you can call your functions with:
(*function_ptr[pick-1])();
or (yuck):
(*(function_ptr + (pick-1)))();
or:
function_ptr[pick-1]();
or:
(function_ptr + (pick-1))();

Related

Using function to pass the user input via pointers not working

I'm trying to get the input from the user input, and pass to the program main using pointer. It seems that the value isn't going through even tho I tried some alternatives.
For example, if i input 0.0001, when I return to the main function it outputs 0.0000
#include <stdio.h>
void inputFloat(float *n);
int main() {
float *number;
printf("Insert number: ");
inputFloat(number);
printf("%1.4f", *number);
return 0;
}
void inputFloat(float *n){
float num;
while (scanf("%f", &num) != 1 || num < 0) {
scanf("%*[^\n]%*c");
printf("insert positive: ");
}
printf("%1.4f\n", num);
n = &num;
}
Thanks in advance for any tip or correction.
The main problem here is that you forget that in C arguments are passed by value, and that includes pointers.
The argument variable n in the inputFloat function is local to the inputFloat function, all modifications (like assignments) to it will be lost once the function returns.
What I believe you are trying to to is emulating pass by reference, which indeed is done by using pointers. But then you pass a pointer to a normal variable using the address-of operator &:
float number; // Not a pointer
inputFloat(&number); // Pass a pointer to the variable number
To use this pointer, and to set the value of the original variable it points to, you need to dereference the pointer:
void inputFloat(float *n)
{
// ...
*n = num; // Copy the value of num to the location where n is pointing
}

Why am I getting an error saying that my function type is conflicting? (edited)

I am trying to write a code in C about a type of encryption.
My code:
#include<stdio.h>
int* number_split(int x)
{
int arr[5],i=0,j=0;
static int ar1[5];
while(x!=0)
{
x=x%10;
arr[i]=x;
++i;
}
for(i=4;i<=0;i--)
{
ar1[j]=arr[i];
++j;
}
return ar1;
}
int main()
{
int n,k,*arr,i=0,l;
printf("Please enter any number:");
scanf("%d",&n);
printf("Please enter a key:");
scanf("%d",&k);
arr=number_split(n);
l=k%5;
for(i=l;i<4;i++)
{
printf("%d\t",arr[i]);
}
for(i=0;i<l;i++)
{
printf("%d\t",arr[i]);
}
return 0;
}
I had looked up into the internet and found that static or globally declared arrays can be returned to other functions. So, I decided to modify my code, but now the problem is that I am getting Segmentation fault(core dumped) and I don't know why. Can someone please help me?
You need to declare your method before using it, like this:
#include<stdio.h>
int* reverse(int* ar);
void number_split(int x)
{
...
or, of course, you could simply move the definition of your reverse method before using it, i.e. before defining the number split method.
So I tried using dynamic memory allocation
Nope, I mean not as far as I can tell, there is no dynamic memory allocation anywhere happening in your code.
You are using a locally defined array instead, and that's why you get this warning (by enabling warnings in your compiler, e.g. Wall, Wextra flags in GCC):
main.c:24:12: warning: function returns address of local variable [-Wreturn-local-addr]
24 | return ar1;
| ^~~
So the issue that here:
int* reverse(int* ar)
{
int ar1[5],i=0,j=0;
// your logic
return ar1;
}
by the time you return the array, the method will have terminated, and since that array was a local variable to that method, it will go out of scope, its lifetime will end (and will be destroyed).
That means, that when the caller would like to use that array, there is no array left in memory to be used, so the caller will just use some memory filled with garbage.
Here, you could dynamically allocate the array, which typically, in a correct program, will stay on memory until you, explicitly, ask for its de-allocation.
error saying that my function type is conflicting?
Because the prototype of the method is:
void number_split(int x);
but you are calling it like this:
arr = number_split(n);
even though its return type is void. Thus the warning:
main.c:34:8: error: void value not ignored as it ought to be
34 | arr=number_split(n);
| ^
number_split is defined as to not return anything:
void number_split(int x)
yet you expect it to return something:
arr=number_split(n);
Even if you define it to return the correct type, which would be
int *number_split(int x)
you let it return a local variable arr. But that variable won't exist after the function returns. So you either need to pass it the array in which to return the result, or let it allocate memory using malloc. I leave that as an excercise for you.
For starters the program does not make sense and if it will even compile has undefined behavior.
For example in this for loop
for(i=sizeof(ar);i<=0;i--)
there is used sizeof( int * ). It seems you mean
for(i=sizeof(ar1);i<=0;i--)
And the function returns a pointer to a local array that will not be alive after exiting the function.
int ar1[5],i=0,j=0;
//...
return ar1;
Or this loop
while(x!=0)
{
x=x%10;
arr[i]=x;
++i;
}
has at most two iterations due to this statement
x=x%10;
It seems you mean
do
{
arr[i] = x % 10;
++i;
} while ( x /= 10 );
The function number_split declared like
void number_split(int x)
has the return type void. But you are using the return type to assign it to a pointer
int n,k,*arr,i=0,l;
// ...
arr=number_split(n);
And the function reverse shall be declared before the function number_split.

Understanding strange return syntax: return(*scriptFunction[x])(arguments);

I know the title for this is horrendous and for this I am sorry; I honestly had no idea how to ask my question as I am not well educated on this matter. Below there is a small bit of code that my question concerns as I have NO idea what is going on or if it is even valid! Although, I suspect it is valid.
return(*scriptFunction[x])(arguments);
From my understanding, you can only return 1 value in C (you can have multiple return statements but that is different and off topic). What is the above statement actually doing?
The code:
return(*scriptFunction[x])(arguments);
actually is only returning one value.
The variable scriptFunction will be an array of function pointers(1). You look up element number x of that array, and call that function, passing the argument arguments. Then the return value from that function is what you return to your caller.
Other than the function pointer aspect, it's no different to return sqrt(42).
By way of example, the following program demonstrates how this can be done:
#include <stdio.h>
// Two simple functions which add a fixed value.
int fnPlus3 (int n) { return n + 3; }
int fnPlus7 (int n) { return n + 7; }
// An array holding those two functions.
int (*scriptFunction[])(int) = { fnPlus3, fnPlus7 };
int main (void) {
// Call first function in array.
int x = 0;
printf ("%d\n", (*scriptFunction[x])(100));
// Then call second one.
x = 1;
printf ("%d\n", (*scriptFunction[x])(100));
return 0;
}
Although it prints the return value from the function rather than returning it again, it still uses the same expression and you can see it calls a different function based on the value of x:
103
107
(1) Or some form of equivalent, such as a pointer to an array of function pointers, or a pointer to a single function pointer (assuming x is always set to zero in that latter case).
Presumably scriptFunction is an array of pointers to functions. *scriptfunction[x] is then the dereferenced pointer to function (the x-th one). Finally, *scriptfunction[x](arguments) represents the invocation of that function applied to arguments, so the result of that function is what's returned in the end.
Side comment: the * is not really necessary. A pointer to function does not need to be dereferenced to call the function, i.e. you can use
return scriptFunction[x](arguments);
instead.
From the looks of it, it seems the line return (*scriptFunction[x])(arguments); scriptFunction is an array of function pointers, and this is simply invoking the function at position indexed by variable x and sending arguments variable contents as its input.
The return value of this invoked function is what ultimately gets returned.
This working example should be useful:
#include <iostream>
using namespace std;
void func_a(int i)
{
cout << "func_a: " << i << endl;
}
void func_b(int i)
{
cout << "func_b: " << i << endl;
}
int main()
{
void (*funcs[])(int) = { func_a, func_b };
for(int i = 0; i < 2; ++i)
(*funcs[i])(i+1);
return 0;
}
The output is below:
➜ /tmp g++ test.cpp -o test
➜ /tmp ./test
func_a: 1
func_b: 2
Also, for future reference, you should consult: How to ask good questions?

Calculate the sum of two numbers using thread

I have this little program I wrote to read two numbers from a user and calculate their sum using a thread function, which is also responsible for displaying the result on the screen.
int global[2];
void *sum_thread(void *arg)
{
int *args_array;
args_array = *(int**)arg;
int n1,n2,sum;
n1=args_array[0];
n2=args_array[1];
sum = n1+n2;
printf("N1 + N2 = %d\n",sum);
return NULL;
}
int main()
{
printf("First number: ");
scanf("%d",&global[0]);
printf("Second number: ");
scanf("%d",&global[1]);
pthread_t tid_sum;
pthread_create(&tid_sum,NULL,sum_thread,(void*)&global);
pthread_join(tid_sum,NULL);
return 0;
}
However, when I run the code, it does not work properly due to a segmentation fault. I suppose I am trying to access/use unallocated memory. Should I allocate it with malloc or is there other things I am doing wrong?
The name of the array, global points to the base address of the array. You can simply pass that and use the same inside your thread function.
However, just to mention a logical point, if you're passing global as a parameter to sum_thread() function, it need not be a global.
In your code, change
pthread_create(&tid_sum,NULL,sum_thread,(void*)&global);
to
pthread_create(&tid_sum,NULL,sum_thread,global);
Then, in sum_thread() function
args_array = *(int**)arg;
to
args_array = arg;
You pass (void*)&global as the thread start function's argument. The type of &global is (*)int[2] -- pointer to array of two int. That is different from and incompatible with int **, which is a pointer to a pointer to int. Arrays are not pointers.
#SouravGhosh already offered a solution that gets the typing correct, and should work just fine. I observe, however, that in this particular case it's a bit silly to pass a pointer to the global array, because the thread could instead just read the array directly:
void *sum_thread(void *arg)
{
int n1,n2,sum;
n1=global[0];
n2=global[1];
sum = n1+n2;
printf("N1 + N2 = %d\n",sum);
return NULL;
}

how can you check if a void function ran successfully with printf?

A friend told me there is a way to check with printf without modifying the original void function.
But I can't see how you can do it.
#include<stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d",test());
}
I kept getting
error: invalid use of void expression
Is there a way to do it?
I see from your edit that you want to do this without modifying the function. You can employ the comma operator to make the function call in a printf:
#include <stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d\n", (test(), 0));
// or even this, to be more explicit:
printf("%s\n", (test(), "test() was called."));
}
The comma operator evaluates the first operand - in this case your function call - and discards the result, then evaluates the second operand and the result is the result of the entire expression.
An example would be to pass memory pointer into the void function and fill it with data you need to see if your void function worked.
void
test_funtion(bool *answer)
{
answer = false;
// do stuff
if(error happens)
return;
answer = true;
return;
}
I don't see how you would use printf to let the program know.
Only way you would use printf for visual logging for yourself, but not the machine.

Resources