C struct to void* pointer - c

I have a struct defined as:
typedef struct {
int type;
void* info;
} Data;
and then i have several other structs that i want to assign to the void* using the following function:
Data* insert_data(int t, void* s)
{
Data * d = (Data*)malloc(sizeof(Data));
d->type = t;
d->info = s;
return d;
}
struct {
...
} Struct#;
then i just call
insert_data(1, variable_of_type_Struct#);
When i compile this it gives a warning
warning: assignment from incompatible pointer type
i tried to cast the variable in the insert to (void*) but didn't work
insert_data(1, (void *) variable_of_type_Struct#);
How can i get rid of this warning?
Thanks

Pass in the address of the struct, not a copy of it (i.e. not passed by value):
insert_data(1, &variable_of_type_Struct);

Pass a pointer to the struct object:
struct your_struct_type bla;
insert_data(1, &bla);

Hope this program helps!
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int type;
void* info;
} Data;
typedef struct {
int i;
char a;
float f;
double d;
}info;
Data* insert_data(int t, void* s)
{
Data * d = (Data*)malloc(sizeof(Data));
d->type = t;
d->info = s;
return d;
}
int main()
{
info in;
Data * d;
d = insert_data(10, &in);
return 0;
}

I'm not quite sure what this was:
struct {
...
} Struct#;
So, I cleaned up your program a little bit and got no warnings, after putting the address of the struct into the call, insert_data(1, &variable_of_type_Struct);
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int type;
void* info;
} Data;
Data* insert_data(int t, void* s);
Data variable_of_type_Struct;
Data* insert_data(int t, void* s)
{
Data * d = (Data*)malloc(sizeof(Data));
d->type = t;
d->info = s;
return d;
}
void test()
{
insert_data(1, &variable_of_type_Struct);
}

insert_data waits for a void*, you put a Data.
insert_data(1, &variable_of_type_Struct#);
It miss a level of indirection.

Related

Is it possible to cast struct pointer to function pointer in c?

From here: ISO C Void * and Function Pointers, I have found a workaround to cast (void*) to function pointer:
int
main(int argc, char *argv[])
{
...
void (*funcp)(void); /* Pointer to function with no arguments */
...
*(void **) (&funcp) = dlsym(libHandle, argv[2]);
}
In other words - to dereference double pointer (another level of indirection).
Now that still assumes, that the final function is of void(*)() type, but I would like to make cast available to other function "types" that can for example accepts some arguments.
Then I found another workaround how to wrap function pointer in struct Why can't I cast a function pointer to (void *)? :
typedef struct
{
void (*ptr)(void);
} Func;
Func vf = { voidfunc };
So I would like to merge these 2 ideas and make possible to pass arbitrary function type as function pointer via struct:
#include <stdio.h>
struct s{
int a, b;
void (*func)();
};
typedef struct{
int (*add)(int,int);
} Func;
int add(int a, int b) { return a+b; }
int main(){
Func f = {add};
struct s foo = {.func=(void*)(&f)};
printf("%i\n",f.add(1,2));
printf("%i\n",foo.func(1,2));
}
Unfortunately, it gives the error:
invalid use of void expression
So the question is, how to cast back the type (void*) to (int*)(int,int) inside of the printf statement?
even if you change the function to return int (int (*func)();) and eventually it will compile, your code is wrong.
Calling the function pointer is in the fact a dereferencing of this pointer.
When you assign the function pointer with the address of the struct, calling this function will actually execute the data inside the struct - not the function referenced struct member. It of course will not be successful.
https://godbolt.org/z/GE464T
The following example is an UB but works on x86 & arm machines and it is only for the illustrational purposes..
struct s{
int a, b;
int (**func)();
};
typedef struct{
int (*add)(int,int);
} Func;
int add(int a, int b) { return a+b; }
int main(){
Func f = {add};
struct s foo = {.func=(void*)(&f)};
printf("%i\n",f.add(1,2));
printf("%i\n",(*foo.func)(1,2));
}
https://godbolt.org/z/rKvGEG
or if you want to use the void (**)() pointer in struct
typedef int func();
struct s{
int a, b;
void (**func)();
};
typedef struct{
int (*add)(int,int);
} Func;
int add(int a, int b) { return a+b; }
int main(){
Func f = {add};
struct s foo = {.func=(void*)(&f)};
printf("%i\n",f.add(1,2));
printf("%i\n",((func *)(*foo.func))(1,2));
}
https://godbolt.org/z/M9qzdf
or
typedef int func();
struct s{
int a, b;
void (*func)();
};
typedef struct{
int (*add)(int,int);
} Func;
int add(int a, int b) { return a+b; }
int main(){
Func f = {add};
struct s foo = {.func=(void*)(&f)};
printf("%i\n",f.add(1,2));
printf("%i\n",(*((func **)foo.func))(1,2));
}
or without typedefs
struct s{
int a, b;
void (*func)();
};
typedef struct{
int (*add)(int,int);
} Func;
int add(int a, int b) { return a+b; }
int main(){
Func f = {add};
struct s foo = {.func=(void*)(&f)};
printf("%i\n",f.add(1,2));
printf("%i\n",(*((int (**)())foo.func))(1,2));
}
https://godbolt.org/z/YG9xd7

Can a pointer point to a struct of item of list of order

typedef struct item
{
char itemName[32];
float price;
int quantity;
}ITEM;
typedef struct list
{
void* item[5];
int (*compare)(void*, void*);
int length;
}LIST;
typedef struct order
{
int orderId;
float orderTotal;
LIST* orderItems;
int length;
} ORDER;
int compareItemPrice(void* p1, void* p2){
ITEM* p = (ITEM*)p1;
ITEM* q = (ITEM*)p2;
if(p->price>q->price)
{
return 1;
} else if(p->price<q->price)
{
return -1;
} else {
return 0;
}
}
Code above is my structures and function wrote in C. When I implement code below, it showed me errors. The errors was all about ITEM* p which was incomplete definition of struct list.
ITEM* getExpensiveItem(ORDER* o){ // Maximum item price
ITEM* p = o->orderItems->item;
ITEM* expensiveItem = p;
for(int i=1; i<o->orderItems->length-1; i++)
{
if(compareItemPrice(p, (p+i)) < 0)
{
expensiveItem = p+i;
}
}
return expensiveItem;
}
Code like
struct a
{
int i;
} A;
will give a variable A that you can use like
A.i = 42;
However, it seems that you really are trying to create a new type. So try:
typedef struct a // Notice the "typedef" in start of line
{
int i;
} A;
That will give a a type A that can be used like:
A var;
A* pVar;
var.i = 42;
pVar = &var;
....
Also notice that your struct order uses the type LIST. So LIST must be declared before struct order. Further, the type CUSTOMER must also be declared which it currently isn't.
So your code should probably be like:
#define N 42 // Made this up as it isn't in your code
typedef struct customer // Made this up as it isn't in your code
{
int x;
} CUSTOMER;
typedef struct list
{
void* item[N];
int (*compare)(void*, void*);
int length;
}LIST;
typedef struct order
{
int orderId;
float orderTotal;
LIST* orderItems;
CUSTOMER* customer;
int length;
} ORDER;
typedef struct item
{
char itemName[32];
float price;
int quantity;
}ITEM;
Also notice that this line has a problem:
ITEM* p = o->orderItems->item;
The type of o->orderItems->item is array of void pointer due to void* item[N]; in struct list. In other words: You are trying to assign an array of pointer to a single pointer. I'm not really sure what you want to do but maybe like:
ITEM* p = o->orderItems->item[0];

C - request for member in something not a structure or union

Long story short I am trying to access a function inside one of my structures. Below is a simplified verson of my code:
#include <stdio.h>
typedef struct
{
void *data;
} A_t;
typedef struct
{
void (*function)(void);
} B_t;
void myfunction(void)
{
fprintf(stdout, "Hello world.\n");
}
int main(int p_argc, char *p_argv[])
{
A_t A;
B_t B;
B.function = myfunction;
A.data = &B;
A.data.function();
return 0;
}
When trying to compile this code I get:
main.c:24:11: error: request for member ‘function’ in something not a structure or union
A.data.function();
Could somebody explain me how to properly access this function via the A-structure?
Thanks
data is of type void *, you need to type cast before de-referencing.
#include <stdio.h>
typedef struct
{
void *data;
} A_t;
typedef struct
{
void (*function)(void);
} B_t;
void myfunction(void)
{
fprintf(stdout, "Hello world.\n");
}
int main(int p_argc, char *p_argv[])
{
A_t A;
B_t B;
B.function = myfunction;
A.data = &B;
((B_t*)(A.data))->function();
return 0;
}

Dereferencing pointer to incomplete type when providing function pointer

I'm getting the dereferencing pointer to incomplete type error when I try to run the following code. I've checked several other questions about this error and from what I can tell it's not due to a missing or extra struct keyword and I believe the pointer type is correct but I could be mistaken.
There might be other issues with the code as I'm just learning C, I'm happy to try and figure them out for myself I just can't seem to track down the issue with the incomplete type error.
Development/C/AI/test/src/test.c: In function ‘compare’:
Development/C/AI/test/src/test.c:10:19: error: dereferencing pointer to incomplete type ‘lrgraph_node {aka struct lrgraph_node}’
if ( strcmp(other->dataType, current->dataType == 0) ) {
test.c
#include "lrGraph.h"
#include <string.h>
int data = 1;
char *dataType = "int";
lrgraph_edge *connected[] = {};
unsigned numEdges = 0;
int compare( lrgraph_node *other, lrgraph_node *current ) {
if ( strcmp(other->dataType, current->dataType == 0) ) {
return (int)other->data - (int)current->data;
}
return -1;
}
int main() {
lrgraph_node *nodeA = lrgraph_createNode((void*)&data, dataType, &compare, connected, numEdges);
lrgraph_printVersion();
}
lrGraph.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lrGraph.h"
struct lrgraph_edge {
float weight;
lrgraph_node *nodeA;
lrgraph_node *nodeB;
};
struct lrgraph_node {
//data can be of any type
void *data;
//string to see if this node can be compared to another node based on data type
char *dataType;
int numEdges;
//comparator function which compares another node to this node
int (*compare)(lrgraph_node *other, lrgraph_node *current);
//array of connected edges
lrgraph_edge *connected[];
};
void lrgraph_printVersion() {
fprintf(stdout, "\nlrgraph version 0.01b\n");
}
lrgraph_node* lrgraph_createNode(void *data, char *dataType, int (*compare)(lrgraph_node* other, lrgraph_node* current), lrgraph_edge *connected[], unsigned numEdges) {
//allocate enough memory for the struct plus each pointer in the array of edges - https://stackoverflow.com/questions/32311269/can-we-have-a-struct-element-of-type-variable-length-array
lrgraph_node *node = malloc(sizeof(lrgraph_node) + numEdges * sizeof(lrgraph_edge));
if (NULL != node) {
node->data = data;
node->dataType = strdup(dataType);
node->compare = compare;
node->numEdges = numEdges;
//initialize each edge in the array
for( unsigned i=0; i < numEdges; i++) {
node->connected[i] = connected[i];
}
}
return node;
}
lrGraph.h
#ifndef LRGRAPH_H
#define LRGRAPH_H
typedef struct lrgraph_node lrgraph_node;
typedef struct lrgraph_edge lrgraph_edge;
lrgraph_node* lrgraph_createNode(void *data, char *dataType, int (*compare)(lrgraph_node *other, lrgraph_node *current), lrgraph_edge *connected[], unsigned numEdges);
void lrgraph_printVersion();
#endif /*LRGRAPH_H*/
"Incomplete type" means the compiler sees you're trying to use a struct type but there is no definition for that struct.
This is fine if you're only using pointers to structs (and is in fact how abstract data types are implemented in C), but if you want to dereference such a pointer, a struct definition must be visible.
In test.c only the contents of lrGraph.h are visible (i.e. typedef struct lrgraph_node lrgraph_node;), but the actual struct lrgraph_node { ... }; definition exists only in lrGraph.c.
Possible solution: Move the struct lrgraph_node { ... } definition into the header. (Alternatively, put the definition of compare into lrGraph.c).

Assignment makes pointer from Integer without a Cast in Structure

I'm making a program that dynamically creates a list of integers.
int ins_dlist(int data, struct dlist **p){
struct dlist *q;
if((*p)->sz == (*p)->maxsz){
q = realloc(*p, DLISTSZ((*p)->maxsz + INCRSZ));
if(q == NULL)
return (-1);
q->maxsz += INCRSZ;
*p = q;
}
//(*p)->item[(*p)->sz++] = data; <-Gives me pointer from integer without cast
*((*p)->item + (*p)->sz++) = data;
return(0);
}
My problem is on *((*p)->item + (*p)->sz++) = data; I tried declaring it in different ways but I still can't get access to the sz variable in my struct.
Heres my struct declaration, its inside a file named dlist.h:
#include <stdlib.h>
struct dlist{
int sz;
int maxsz;
int *item[1];
};
#define INITSZ 5
#define INCRSZ 5
#define DLISTSZ(n) ((size_t)(sizeof(struct dlist)) + ((n-1)*sizeof(int)))
struct dlist *init_dlist(int num);
int ins_dlist(int data, struct dlist **p);
You probably wanted to define dllist as:
struct dlist{
int sz;
int maxsz;
int item[1];
};

Resources