C function pointer and struct - c

I am new to C function pointer and structure. Here is what I want to achieve say there is a structure
typedef struct gfcrequest_t gfcrequest_t;
Later on this struct will be used to point to a function and the function will be called
gfcrequest_t *gfc_create();
gfr = gfc_create();
gfc_set_server(&gfr, server);
gfc_set_port(&gfr, port);
So are the following codes correct to initiate and later on I could add elements like server name and port number?
gfcrequest_t *gfc_create() {
struct out {
struct hostent *server;
int portno;
};
return out;
}
void gfc_set_port(gfcrequest_t **gfr, unsigned short port) {
gfr.portno = port;
}
void gfc_set_server(gfcrequest_t **gfr, const char *server) {
gfr.server = gethostbyname(server);
}

thats not how you do pointers to function.
to declare a pointer to function you do this:
if your function is:
int ft_somefink (int a, int b);
the pointer should be:
struct s_structure;
typedef struct s_structure t_structure;
struct s_structure
{
int (*funct)(int, int);
};
the typedef is there to simplify syntax.
its just an alias to avoid having to type "struct" everytime you use the structure.
you initialize it like so:
int main ()
{
t_structure name;
name.funct = &ft_somefink;
}
And call it like so:
int main()
{
t_structure name;
int a;
int b;
a = 1;
b = 2;
name.funct = &ft_somefink;
...
name.funct(a, b);
}
or like so if you pass the structure as pointer, it should look like this:
the main:
int main ()
{
t_structure *name;
...
function_somthing_useful(&name);
}
and the function:
void function_something_useful(t_structure **name)
{
if (!(*name = malloc(sizeof(t_structure))))
{
fprintf(stderr, "malloc error, not enough memory or swap nvm\n")
return ;
}
name->funct = &ft_somefink;
}
And, obviously, you call it then by:
name->funct(a, b);
note that you can malloc in main, doesnt matter. the idea to pass just the pointer is to avoid having to copy the whole structure everytime you pass it to a function.
the difference between . and -> operator is a dereferencing, but that would be another subject.
also i think it is better to pass the function as a pointer, instead of the whole thing because that might imply copying all of the functions instructions. not 100% sure of that tho... or rather depends on the system.
on linux reads are suposed to be "atomic", which, in my experience includes what happens on the stack. couldnt speak about other systems tho...
definitely could use someone to fill in the blanks here...

Related

Segmentation fault in cast struct in c

In an attempt to encapsulate struct members (in a similar way as discussed in this question), I created the code below.
In the code below, I have a c-struct, which contains methods to access members of the struct which are hidden (by being cast into a struct otherwise the same but without the hidden properties)
#include <stdio.h>
typedef struct class {
int publicValue;
int (*getPV)();
void (*setPV)(int newPV);
} class;
typedef struct classSource {
int publicValue;
int apv;
int (*getPV)();
void (*setPV)(int newPV);
int PV;
} classSource;
class class_init() {
classSource cs;
cs.publicValue = 15;
cs.PV = 8;
int class_getPV() {
return cs.PV;
};
void class_setPV(int x) {
cs.PV = x;
};
cs.getPV = class_getPV;
cs.setPV = class_setPV;
class *c = (class*)(&cs);
return *c;
}
int main(int argc, const char * argv[]) {
class c = class_init();
c.setPV(3452);
printf("%d", c.publicValue);
printf("%d", c.getPV());
return 0;
}
When I run this, I get a segmentation fault error. However, I noticed that if I comment out certain lines of code, it (seems) to work okay:
#include <stdio.h>
typedef struct class {
int publicValue;
int (*getPV)();
void (*setPV)(int newPV);
} class;
typedef struct classSource {
int publicValue;
int apv;
int (*getPV)();
void (*setPV)(int newPV);
int PV;
} classSource;
class class_init() {
classSource cs;
cs.publicValue = 15;
cs.PV = 8;
int class_getPV() {
return cs.PV;
};
void class_setPV(int x) {
cs.PV = x;
};
cs.getPV = class_getPV;
cs.setPV = class_setPV;
class *c = (class*)(&cs);
return *c;
}
int main(int argc, const char * argv[]) {
class c = class_init();
c.setPV(3452);
//printf("%d", c.publicValue);
printf("%d", c.getPV());
return 0;
}
I presume that it might have something to do with using the initializer to add the getter and setter methods to the struct, as those might overwrite memory.
Is what I am doing undefined behavior? Is there a way to fix this?
EDIT: With the help of the answer below, I have re-written the code. In case anyone wants to see the implementation, below is the revised code
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int pub;
} class;
typedef struct {
class public;
int PV;
} classSource;
int class_getPV(class *c) {
return ((classSource*)c)->PV;
}
void class_setPV(class *c, int newPV) {
((classSource*)c)->PV = newPV;
}
class *class_init() {
classSource *cs = malloc(sizeof(*cs));
if((void*)cs == (void*)NULL) {
printf("Error: malloc failed to allocate memory");
exit(1);
}
cs->public.pub = 10;
cs->PV = 8;
return &(cs->public);
}
int main() {
class *c = class_init();
class_setPV(c,4524);
printf("%d\n",class_getPV(c));
printf("%d\n",c->pub);
free(c);
return 0;
}
There are at least three separate problems in your code.
You don't actually have a "struct otherwise the same but without the hidden properties". Your class and classSource structs have their getPV and setPV members in different places. Internally member access boils down to byte offsets from the beginning of the struct. To have a fighting chance of working, your code would need to have a common initial prefix of members between the two struct types (i.e. get rid of int apv; or move it to the end).
You're returning a struct by value, which automatically makes a copy. You've reimplemented the object slicing problem: Because the return value has type class, only the members of class will be copied. The extra members of classSource have been "sliced off".
You're using nested functions. This is not a standard feature of C; GCC implements it as an extension and says:
If you try to call the nested function through its address after the containing function exits, all hell breaks loose.
This is exactly what's happening in your code: You're calling c.setPV(3452); and c.getPV after class_init has returned.
If you want to fix these problems, you'd have to:
Fix your struct definitions. At minimum all members of class need to appear at the beginning of classSource in the same order. Even if you do that, I'm not sure you wouldn't still run into undefined behavior (e.g. you might be violating an aliasing rule).
I'm somewhat sure that embedding one struct in the other would be OK, however:
typedef struct classSource {
class public;
int PV;
} classSource;
Now you can return &cs->public from your initializer, and your methods can cast the class * pointer back to classSource *. (I think this is OK because all struct pointers have the same size/representation, and X.public as the first member is guaranteed to have the same memory address as X.)
Change your code to use pointers instead. Returning a pointer to a struct avoids the slicing problem, but now you have to take care of memory management (malloc the struct and take care to free it later).
Don't use nested functions. Instead pass a pointer to the object to each method:
class *c = class_init();
c->setPV(c, 3452);
int x = c->getPV(c);
This is somewhat tedious, but this is what e.g. C++ does under the hood, essentially. Except C++ doesn't put function pointers in the objects themselves; there's no reason to when you can either use normal functions:
setPV(c, 3452);
int x = getPV(c);
... or use a separate (global, constant, singleton) struct that just stores pointers to methods (and no data). Each object then only contains a pointer to this struct of methods (this is known as a vtable):
struct classInterface {
void (*setPV)(class *, int);
int (*getPV)(const class *);
};
static const classInterface classSourceVtable = {
class_setPV, // these are normal functions, defined elsewhere
class_getPV
};
Method calls would look like this:
c->vtable->setPV(c, 1234);
int x = c->vtable->getPV(c);
But this is mainly useful if you have several different struct types that share a common public interface (class) and you want to write code that works uniformly on all of them.

Can there be functions inside structures?

Can we have functions in structures in C language?
Could someone please give an example of how to implement it and explain?
No, structures contain data only. However, you can define a pointer to a function inside of a struct as below:
struct myStruct {
int x;
void (*anotherFunction)(struct foo *);
}
The answer is no, but there is away to get the same effect.
Functions can only be found at the outermost level of a C program. This improves run-time speed by reducing the housekeeping associated with function calls.
As such, you cannot have a function inside of a struct (or inside of another function) but it is very common to have function pointers inside structures. For example:
#include <stdio.h>
int get_int_global (void)
{
return 10;
}
double get_double_global (void)
{
return 3.14;
}
struct test {
int a;
double b;
};
struct test_func {
int (*get_int) (void);
double (*get_double)(void);
};
int main (void)
{
struct test_func t1 = {get_int_global, get_double_global};
struct test t2 = {10, 3.14};
printf("Using function pointers: %d, %f\n", t1.get_int(), t1.get_double());
printf("Using built-in types: %d, %f\n", t2.a, t2.b);
return 0;
}
A lot of people will also use a naming convention for function pointers inside structures and will typedef their function pointers. For example you could declare the structure containing pointers like this:
typedef int (*get_int_fptr) (void);
typedef double (*get_double_fptr)(void);
struct test_func {
get_int_fptr get_int;
get_double_fptr get_double;
};
Everything else in the code above will work as it is. Now, get_int_fptr is a special type for a function returning int and if you assume that *_fptr are all function pointers then you can find what the function signature is by simply looking at the typedef.
No, it has to be implemented like this :
typedef struct S_House {
char* name;
int opened;
} House;
void openHouse(House* theHouse);
void openHouse(House* theHouse) {
theHouse->opened = 1;
}
int main() {
House myHouse;
openHouse(&myHouse);
return 0;
}

Use function pointer in struct - C compiler

I found an answer how to make function pointer in struct but I am still curious about
its operation. Can anybody explain this clearly?
Here is my question,
This code runs properly but...
char func_1(void);
char func_2(char);
struct mStruct
{
char name[100];
int age;
char (*func_1)(void);
void (*func_2)(char);
};
void init_struct(struct mStruct *pStruct)<-why this void function is necessary?
{
if(pStruct == NULL) {
pStruct = malloc(sizeof(struct mStruct));
}
(*pStruct).age = 25;
(*pStruct).func1 = &func1;
(*pStruct).func2 = &func2;
}
char func_1(void)
{
... ;
}
char func_2(char)
{
... ;
}
I already tried to eliminate the init_struct function, but all tries failed. My gcc compiler only accepts it as above. Does anybody know another way to initialize the struct without using a function
or why it is only acceptable as a void function?
Actually, besides the title, your question seems to have nothing to do with function pointers.
You have a struct mStruct with some members. For your question, it does not really matter what these members are.
With this struct, you don't need an initialization function. You can always simply use the struct and initialize it:
struct mStruct s;
s.member = 20;
But, this comes with a cost: You repeat yourself and when you want to change the struct (say, add another member), you will have to change lot of places. That's bad and can be fixed with an initialization function:
void init_struct(struct mStruct *pStruct)
{
pStruct->member = 20;
}
struct mStruct s;
init_struct(&s);
Now, you should not add other responsibilities to init_struct than to initialize it. In your example, you also allocate memory for the struct, in a buggy way. Instead, use another function for that:
struct mStruct* create_struct()
{
struct mStruct *pStruct = (struct mStruct*) malloc(sizeof(struct mStruct));
init_struct(pStruct);
return pStruct;
}
struct mStruct *pStruct = create_struct();
do_something_with(pStruct);
free(pStruct); // Don't forget this!
If you need more cleanup than just freeing the memory, write yet another function for it:
void destroy_struct(struct mStruct *pStruct)
{
cleanup(pStruct);
free(pStruct);
}
struct mStruct *pStruct = create_struct();
do_something_with(pStruct);
destroy_struct(pStruct); // Don't forget this!

Pointer at function: access the data inside a structure?

I listed some example code below and the question is if there is a way for the function_name to access the value of number from struct_name?
typedef struct struct_name {
int number
void (*func)();
} * struct_name_ptr;
void function_name() {
//access number from struct
}
main() {
struct_name_ptr newobject;
newobject->func=&function_name;
newobject->func(); //can it print the value of the number in the structure above?
}
Uh - no.
A struct can certainly contain a function pointer. But the function you call wouldn't have any knowledge of the struct. Unless you passed a pointer as a function argument, or made the struct global.
With my limited knowledge of programming, I don't think this is possible. Though the struct contains a function pointer, the address of the function assigned to it is different and I don't think there will be anyway for it to access it unless you pass it as an argument.
Well, two things, struct_name->number should have a value, and it either needs to be in the same scope as &function_name or it needs to be explicitly passed. Two ways to do it:
/* Here is with a global calling struct */
#include<stdio.h>
typedef struct struct_name {
int number;
void (*func)();
} * struct_name_ptr;
struct struct_name newobject = { 0 };
void function_name() {
printf("%d",struct_name);
}
void main() {
struct struct_name_ptr newobject;
newobject->func=&function_name;
newobject->func();
}
/* And one with a modified function_name */
#include<stdio.h>
typedef struct struct_name {
int number;
void (*func)();
} * struct_name_ptr;
void function_name(struct_name) {
printf("%d",struct_name);
}
void main() {
struct struct_name_ptr newobject;
newobject.number = 0;
newobject->func=&function_name;
newobject->func(newobject);
}
No, a pizza won't ever know what the pizza delivery guy, who delivered it, looks like.
A regular function is just an address in memory. It can be called using a function pointer like in this case. In any case: The function won't know how it was called. In particular it won't know that it was called using a function pointer that's part of (a piece of memory corresponding to) some struct.
When using a language with classes like C++, member functions will have a hidden argument which is a pointer to the class instance. That's how member functions know about their data.
You can 'simulate' a simple OOP in plain C, for your example like:
typedef struct {
int number;
void (*func)();
} class;
void function_name(class *this) {
printf("%d",this->number);
}
#define CALL(c,f) c.f(&c)
int main() {
class object={12345,function_name};
CALL(object,func); // voilá
}

Passing struct to function

I'm a new C programmer and I wanted to know how I can pass a struct through to a function. I'm getting an error and can't figure out the correct syntax to do it. Here is the code for it....
Struct:
struct student{
char firstname[30];
char surname[30];
};
struct student person;
Call:
addStudent(person);
Prototype:
void addStudent(struct student);
and the actual function:
void addStudent(person)
{
return;
}
Compiler errors:
line 21: warning: dubious tag declaration: struct student
line 223: argument #1 is incompatible with prototype:
This is how to pass the struct by reference. This means that your function can access the struct outside of the function and modify its values. You do this by passing a pointer to the structure to the function.
#include <stdio.h>
/* card structure definition */
struct card
{
int face; // define pointer face
}; // end structure card
typedef struct card Card ;
/* prototype */
void passByReference(Card *c) ;
int main(void)
{
Card c ;
c.face = 1 ;
Card *cptr = &c ; // pointer to Card c
printf("The value of c before function passing = %d\n", c.face);
printf("The value of cptr before function = %d\n",cptr->face);
passByReference(cptr);
printf("The value of c after function passing = %d\n", c.face);
return 0 ; // successfully ran program
}
void passByReference(Card *c)
{
c->face = 4;
}
This is how you pass the struct by value so that your function receives a copy of the struct and cannot access the exterior structure to modify it. By exterior I mean outside the function.
#include <stdio.h>
/* global card structure definition */
struct card
{
int face ; // define pointer face
};// end structure card
typedef struct card Card ;
/* function prototypes */
void passByValue(Card c);
int main(void)
{
Card c ;
c.face = 1;
printf("c.face before passByValue() = %d\n", c.face);
passByValue(c);
printf("c.face after passByValue() = %d\n",c.face);
printf("As you can see the value of c did not change\n");
printf("\nand the Card c inside the function has been destroyed"
"\n(no longer in memory)");
}
void passByValue(Card c)
{
c.face = 5;
}
The line function implementation should be:
void addStudent(struct student person) {
}
person is not a type but a variable, you cannot use it as the type of a function parameter.
Also, make sure your struct is defined before the prototype of the function addStudent as the prototype uses it.
When passing a struct to another function, it would usually be better to do as Donnell suggested above and pass it by reference instead.
A very good reason for this is that it makes things easier if you want to make changes that will be reflected when you return to the function that created the instance of it.
Here is an example of the simplest way to do this:
#include <stdio.h>
typedef struct student {
int age;
} student;
void addStudent(student *s) {
/* Here we can use the arrow operator (->) to dereference
the pointer and access any of it's members: */
s->age = 10;
}
int main(void) {
student aStudent = {0}; /* create an instance of the student struct */
addStudent(&aStudent); /* pass a pointer to the instance */
printf("%d", aStudent.age);
return 0;
}
In this example, the argument for the addStudent() function is a pointer to an instance of a student struct - student *s. In main(), we create an instance of the student struct and then pass a reference to it to our addStudent() function using the reference operator (&).
In the addStudent() function we can make use of the arrow operator (->) to dereference the pointer, and access any of it's members (functionally equivalent to: (*s).age).
Any changes that we make in the addStudent() function will be reflected when we return to main(), because the pointer gave us a reference to where in the memory the instance of the student struct is being stored. This is illustrated by the printf(), which will output "10" in this example.
Had you not passed a reference, you would actually be working with a copy of the struct you passed in to the function, meaning that any changes would not be reflected when you return to main - unless you implemented a way of passing the new version of the struct back to main or something along those lines!
Although pointers may seem off-putting at first, once you get your head around how they work and why they are so handy they become second nature, and you wonder how you ever coped without them!
You need to specify a type on person:
void addStudent(struct student person) {
...
}
Also, you can typedef your struct to avoid having to type struct every time you use it:
typedef struct student{
...
} student_t;
void addStudent(student_t person) {
...
}
Instead of:
void addStudent(person)
{
return;
}
try this:
void addStudent(student person)
{
return;
}
Since you have already declared a structure called 'student' you don't necessarily have to specify so in the function implementation as in:
void addStudent(struct student person)
{
return;
}

Resources