This question already has answers here:
How can I call a function using a function pointer?
(16 answers)
Closed 1 year ago.
I have a struct with a function pointer, that is intended for pointing to the bar() function, but i have no clue how to call the function that's being pointed on:
#include <stdlib.h>
typedef struct Foo
{
int (*func_ptr)(const char *, const char *);
} Foo;
int bar(const char *a, const char *b)
{
return 3;
}
int main(void)
{
Foo *foo = (Foo *)malloc(sizeof(Foo));
foo->func_ptr = &bar;
//how do i call the function?
return 0;
}
Imagine your const char *a is "hello" and const char *b is "there", then you can use any of the following forms to call the function by its pointer:
(foo->func_ptr)("hello", "there");
(*foo->func_ptr)("hello", "there");
foo->func_ptr("hello", "there");
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have an example code as below, because I'm not familiar with the function pointer so that I cannot find out what is happening at
ret = (p_local->str)(10,b_in); (segmentation fault)
#include "stdio.h"
typedef int (*check)(const int a, char * const b[]);
typedef struct ST_T_COMMAND
{
char *chuoi;
check str;
} T_COMMAND;
const T_COMMAND *p_global;
int main()
{
int ret;
const T_COMMAND *p_local;
char *b_in[] = {"1234", "abchd"};
T_COMMAND str_new;
p_global = &str_new;
str_new.chuoi = "1234";
p_local = p_global;
if(strcmp(p_local->chuoi, b_in[0]) == 0)
{
ret = (p_local->str)(10, b_in);
printf("ret = %d\n", ret);
}
else
{
printf("else\n");
}
return 0;
}
I want to pass that segmentation fault. And please tell me what is wrong with my code
Here
typedef int (*check)(const int a, char * const b[]);
you have declared the function pointer i.e check is the function pointer name, it can points to any function whose input argument are int and char* const [] type & which returns int type.
And here
ret = (p_local->str)(10, b_in); /* calling via function pointer */
you are trying to call via function pointer but you haven't initialized function pointer anywhere. You need to initialize function pointer first before calling it.
Also
const T_COMMAND *p_local; /* initialize it here itself */
above syntax means where p_local points that is constant i.e when you will do like
p_local->str = funHandler;
as I did below, compiler will not allow it to modify.
Same with p_global, if you make this as const earlier, you can't do like
const T_COMMAND *p_global;
p_local = p_global; /* not possible due to above const declaration of p_global */
Try this version:
#include <stdio.h>
#include <string.h>
typedef int (*check)(const int a, char * const b[]);
typedef struct ST_T_COMMAND
{
char *chuoi;
check str;
}T_COMMAND;
T_COMMAND *p_global; /* removed const */
int funHandler(int num, char* const buf[10])
{
printf("in funHandler() %d %s\n", num, buf[0]);
return num;
}
int main(void)
{
int ret;
T_COMMAND *p_local; /* removed const */
char * b_in[] = {"1234","abchd"};
T_COMMAND str_new;
p_global = &str_new;
str_new.chuoi = "1234";
p_local = p_global;
if(strcmp(p_local->chuoi,b_in[0]) == 0)
{
p_local->str = funHandler; /* initialize function pointer, you missed this */
ret = (p_local->str)(10,b_in);
printf("ret = %d\n",ret);
}
else
{
printf("else\n");
}
return 0;
}
ret = (p_local->str)(10,b_in);
You are calling the function p_local->str without initializing it first.
You need to set a value to plocal->str (or any of the equivalent values in your program i.e. p_global, str_new)
This value should be a function that you have defined elsewhere which matches the type of the function pointer i.e. parameters of const int a and char * const b[]
This question already has answers here:
C function pointer syntax
(4 answers)
Closed 4 years ago.
I'm trying to get this code to run..
#include <stdio.h>
int *myMethod(int *a)
{
printf("Hello");
return a;
}
int main()
{
// my_ptr is a pointer to function myMethod()
int *my_ptr(int *) = myMethod;
// Invoking myMethod() using my_ptr
int a = 5;
int *p = (*my_ptr)(&a);
printf("Bye %d\n", *p);
return 0;
}
I thought my syntax for a function pointer, my_ptr, would be correct where it could take an int pointer as it's parameter and return an int pointer but when I compile it, I get the error that:
error: function 'my_ptr' is initialized like a variable
int *my_ptr(int *) = myMethod;
Could someone explain the error/issue? Thanks!
int* my_ptr(int*) is the prototype of a function. You want a function pointer: int* (*my_ptr)(int*)
Change pointer to function myMethod to this:
int *(*my_ptr)(int *) = &myMethod;
You should use int *(*my_ptr)(int *) = myMethod; not int *my_ptr(int *) = myMethod;
The following code could work:
#include <stdio.h>
int *myMethod(int *a)
{
printf("Hello");
return a;
}
int main()
{
int *(*my_ptr)(int *) = myMethod;
int a = 5;
int *p = (*my_ptr)(&a);
printf("Bye %d\n", *p);
return 0;
}
my question deals with creating variables that are visible throughout the program file. In other words, a file-local variable.
Consider this example
#include <stdio.h>
struct foo
{
char s[] = "HELLO";
int n = 5;
};
struct foo *a;
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a->s);
printf("%d\n",a->n);
return 0;
}
Now, this code snippet won't run.
Why?
Because the structure pointed to be pointer variable a will not get allocated as the statement never executed.
Now, how do you get it allocated without changing the scope of this variable a?
#include <stdio.h>
struct foo {
char const *s;
int n;
};
/* static for file-local */
static struct foo a = { "HELLO" , 5 };
int main(void) {
printf("%s\n", a.s);
printf("%d\n", a.n);
return 0;
}
Now, how do you get it allocated without changing the scope of this variable a?
I am sure there a lot of ways to solve your problem. Here's my suggestion.
Change the definition of struct foo to contain a fixed number of characters in s.
Create a as an object instead of a pointer. Initialize it with the necessary values.
Make a a static variable so its use is limited to the file only.
Use the object a instead of the pointer a in rest of the file.
#include <stdio.h>
struct foo
{
char s[20];
int n;
};
static struct foo a = {"HELLO", 20};
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
return 0;
}
This:
struct foo
{
char s[] = "HELLO";
int n = 5;
};
Is not valid C code. You first declare the type:
struct foo
{
char s[10];
int n;
};
Then define a variable of that type:
static struct foo a = { "HELLO", 5 };
The static keyword allows this variable to have file local scope.
You can now use it like this:
static struct foo a = { "HELLO", 5 };
void other()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
}
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
other();
return 0;
}
Note that a is accessible from both functions. It will not however be viewable from functions defined in other files because it is declared as static.
As for using a pointer vs the struct directly, you can take the address of this structure at any time you need to use it in that way:
some_function(&a);
well, i need to use a pointer instead of a structure directly
Try this:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
struct foo{
char s[20];
int n;
};
int main(void){
struct foo *a;
a = malloc(sizeof(struct foo));
puts("Dummy outputs!\n");
strcpy(a->s, "HELLO");
a->n = 5;
printf("%s\n",a->s);
printf("%d\n",a->n);
free(a);
return 0;
}
Output:
Dummy outputs!
HELLO
5
This question already has an answer here:
Pointer losing its value + execv compilation warning
(1 answer)
Closed 7 years ago.
I have started to work on a program which implements a structure called "PhoneBook" having two members: "length" and "allocatedSpace", both of type "unsigned int". The structure is dynamically allocated. The two members of the structure are assigned in an external function called "InitializePhoneBook". Now, when I try to print the values of the two members of the structure inside the "main" function I get a "Segmentation fault" error.
PhoneBook.h
#ifndef PHONEBOOK_H
#define PHONEBOOK_H
struct PhoneBook
{
unsigned int length;
unsigned int allocatedSpace;
};
void InitializePhoneBook(struct PhoneBook *phoneBook);
void ClearPhoneBook(struct PhoneBook *phoneBook);
#endif
PhoneBook.c
#include <stdlib.h>
#include "PhoneBook.h"
void InitializePhoneBook(struct PhoneBook *phoneBook)
{
phoneBook = malloc(sizeof(struct PhoneBook) * 1);
phoneBook->length = 0;
phoneBook->allocatedSpace = 1000;
}
void ClearPhoneBook(struct PhoneBook *phoneBook)
{
free(phoneBook);
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "PhoneBook.h"
int main(void)
{
struct PhoneBook *phoneBook;
InitializePhoneBook(phoneBook);
printf("%d %d\n", phoneBook->length, phoneBook->allocatedSpace);
ClearPhoneBook(phoneBook);
return 0;
}
Running "./a.out" with "gdb" I get:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400621 in main () at ./main.c:12
12 printf("%u %u\n", phoneBook->length, phoneBook->allocatedSpace);
When you do malloc in InitializePhoneBook():
phoneBook = malloc(sizeof(struct PhoneBook) * 1);
It doesn't modify the pointer in main because the pointer you assign is local the function. Pass a pointer to pointer or rewrite the function return the malloced pointer.
void InitializePhoneBook(struct PhoneBook **phoneBook)
{
*phoneBook = malloc(sizeof(struct PhoneBook) * 1);
(*phoneBook)->length = 0;
(*phoneBook)->allocatedSpace = 1000;
}
call in main():
InitializePhoneBook(&phoneBook);
and change the prototype:
void InitializePhoneBook(struct PhoneBook **phoneBook);
Other issues I noticed:
You should also check the result of malloc for failure.
Use %u format specifier to print unsigned ints.
C is pass by value. Which means that the parameters are copied when calling a function. Your function InitializePhoneBook() will copy the non-initialised pointer, will assign to that copy the return value of malloc() and then forget that value when leaving the function. Your caller will continue with the un-initialized original.
Your function InitializePhoneBook() can be changed in 2 ways:
struct PhoneBook *InitializePhoneBook(void)
{
struct phoneBook *pb = malloc(sizeof(struct PhoneBook) * 1);
pb->length = 0;
pb->allocatedSpace = 1000;
return pb;
}
or
void InitializePhoneBook(struct PhoneBook **pPhoneBook)
{
*pPhoneBook = malloc(sizeof(struct PhoneBook) * 1);
(*pPhoneBook)->length = 0;
(*pPhoneBook)->allocatedSpace = 1000;
}
the call in main would have to be changed
struct PhoneBook *phoneBook = InitializePhoneBook();
or
struct PhoneBook *phoneBook;
InitializePhoneBook(&phoneBook);
respectively.
The scope of the malloced pointer remains inside the InitializePhoneBook function.
For that you must return the pointer to the main so change the prototype to:
struct PhoneBook *InitializePhoneBook(struct PhoneBook *);
and the last statement of the above function should be:
return phoneBook;
and inside main call it this way:
phoneBook=InitializePhoneBook(phoneBook);
After some research I didn't find a good way to implement the std::bind in C.
I build a small program that implements an equivalent of std::bind in C by hacking the stack.
There's two functions I will try to bind to function with pre-defined arguments.
My problem is this code is only working under Windows. Under Linux, this is a mess. I this the problem is my knowledge of the stack and the way that arguments are store in memory.
Thanks,
Please, find below the code I made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
The two functions I want to bind :
void test1 (int nombre, char t, int nombre2)
{
printf ("test 1 : %d%c%d\n", nombre, t, nombre2);
}
void test2 (char t, int nombre, int nombre2)
{
printf ("test 2 : %c%d%d\n", t, nombre, nombre2);
}
Two struct that will store the argument of each function (order of fields is important).
typedef struct {
int nombre;
char t;
int nombre2;
} struct1;
typedef struct {
char t;
int nombre;
int nombre2;
} struct2;
This "fake" struct will be use to write on the stack by dereferencing a structvoid* variable.
// Size must be bigger than every struct*
typedef struct {
int i[10];
} structvoid;
The main function.
int main(int argc, char** argv) {
// Variables to store the two functions and their arguments.
void * functions[2];
structvoid * data[2];
void *func1 = (void *)&test1;
void *func2 = (void *)&test2;
void (*functionPtrc)(structurevoid);
// Definition of the argument of the first function test1
struct1 data1;
data1.nombre = 15;
data1.t = 'c';
data1.nombre2 = 30;
// and storing data.
void *datac = malloc (sizeof (structvoid));
memcpy(datac, &data1, sizeof (struct1));
data[0] = (structvoid*)datac;
functions[0] = func1;
// Same thing with function 2.
struct2 data2;
data2.t = 'a';
data2.nombre = 5;
data2.nombre2 = 10;
datac = malloc (sizeof (structvoid));
memcpy(datac, &data2, sizeof (struct2));
data[1] = (structvoid*)datac;
functions[1] = func2;
// Get the pointer to the first function (test1);
functionPtrc = functions[0];
// All the hack is here. By dereferencing the data, this will write on the stack all arguments need by the test1 function.
functionPtrc(*data[0]);
functionPtrc = functions[1];
functionPtrc(*data[1]);
// To check the result.
test1 (data1.nombre, data1.t, data1.nombre2);
test2 (data2.t, data2.nombre, data2.nombre2);
return 0;
}
EDIT
Here a new version of the program by calling function via the calling convention. I only wrote the new lines. The problem of this method is I can only store data inside a "void *" field. If I increase the size of structvoid, I got garbage behaviors.
// Structure that memories each argument
typedef struct {
void *i[1];
} structvoid;
int main(int argc, char** argv) {
// Variables to store the two functions and their arguments.
void * functions[2];
structvoid * data[2];
void *func1 = (void *)&test1;
// Let's start with a maximum of 5 arguments
void (*functionPtrc)(structurevoid, structurevoid, structurevoid, structurevoid, structurevoid);
// Definition of the argument of the first function test1
struct1 data1;
data1.nombre = 15;
data1.t = 'c';
data1.nombre2 = 30;
// and storing data.
structvoid *datac = malloc (sizeof (structvoid)*5);
memcpy(&datac[0], &data1.nombre, sizeof (data1.nombre));
memcpy(&datac[1], &data1.t, sizeof (data1.t));
memcpy(&datac[2], &data1.nombre2, sizeof (data1.nombre2));
data[0] = datac;
functions[0] = func1;
// Get the pointer to the first function (test1);
functionPtrc = functions[0];
// Call the function with the arguments. The unused argument will be ignored.
functionPtrc(data[0][0], data[0][1], data[0][2], data[0][3], data[0][4]);
}