Move a struct through (void *) function argument back to struct - c

I am trying to send a struct through a function, taking (void *) as a singular argument, and then signing it to a struct of the same type (as in main/before function) inside the function. This results in error every single way I attempt to do it. Anyone knows how to do this?
struct a
{
SDL_Surface *s;
};
struct b
{
SDL_Window *window;
};
struct struct_of_structs
{
struct a *struct_a;
struct b *struct_b;
};
void loop(void *arg)
{
struct_of_structs s_structs;
// how do I assign arg to s_structs?
s_structs = arg; // error
s_structs = *arg; // error
s_structs = &arg; // error
*s_structs = arg; // error
&s_structs = arg; // error
*s_structs = *arg; // error
*s_structs = &arg; // error
&s_structs = *arg; // error
&s_structs = &arg; // error
}
int main()
{
struct struct_of_structs struct_struct;
struct a a_struct;
struct b b_struct;
struct_struct.a = a_struct;
struct_struct.b = b_struct;
loop(&struct_struct);
}
Edit I have uploaded my original code at pastebin. Whatever order of pointer or casting I add to the "arg" inside the loop, I get the error:
error: expected expression
arguments = (*(loop_args*)arg);
error: use of undeclared identifier 'loop_args'
in every way I add the casting. Doing struct loop_args arguments* = ((loop_args*)arg) does not work, etc, etc. It always fails with "expected expression blah blah".
P.S. adding your solution to a random main.c using the dummy code worked and I learned something new, thanks a lot!

s_structs = (*(struct_of_structs *)arg);
should do the trick.
basically what happens is you send a pointer to a struct but the function receives it as a void pointer, so to go from a void * to a struct you can't dereference a void *, so you cast the argument to a struct_of_structs pointer, and dereference it which will result in what you are looking for.

You need to create a pointer, not a new struct.
void loop(void *arg)
{
struct_of_structs *ps_structs =0;
// how do I assign arg to s_structs?
ps_structs = (struct_of_structs *) arg; // error
}

With the help of all the answers as well as the comments, I solved it!
struct_of_structs s_structs* = (struct struct_of_structs*)arg;
I cannot simply cast it to a struct of type "struct_of_structs", need to cast it to a type that is a struct aka "struct struct_of_structs"! Thanks everyone!

Related

Writing an Address to a Pointer in a struct with a function fails

I have two structs pbuf and netif, and assigned two variables (local_pbuf, local_netif) with them. These variables hold some data. There is another struct called wrapper_p_n, which holds two pointers of the type pbuf and netif. My goal is to write a function which hand over the variables local_pbuf and local_netif by call by reference and then wraps the two pointers in a single struct called wrapper_p_n. Then I want to use call by reference to give wrapper_p_n to another function. Unfortunately I get the Error message:
[Error] cannot convert 'pbuf**' to 'pbuf*' in assignment
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
struct pbuf{
int a;
int b;
};
struct netif{
int c;
int d;
};
struct wrapper_p_n{ // wrapper for pbuf- and netif-struct pointer
struct pbuf *wp_val_p;
struct netif *wp_val_n;
};
void rx_local_p_n(struct pbuf *rx_pbuf, struct netif *rx_netif)
{
// wrap the received pointer
struct wrapper_p_n *local_w_p_n;
local_w_p_n->wp_val_p = &rx_pbuf;
local_w_p_n->wp_val_n = &rx_netif;
/*Passing *local_w_p_n pointer to another function: Example: */
/*ex_function(&local_w_p_n)*/
}
int main(int argc, char** argv) {
// give values to local_pbuf and netif
struct pbuf local_pbuf;
local_pbuf.a = 1;
local_pbuf.b = 2;
struct netif local_netif;
local_netif.c = 3;
local_netif.d = 4;
//passing pbuf- and netif-stuct to function
rx_local_p_n(&local_pbuf, &local_netif);
return 0;
}
In the function void rx_local_p_n you pass in pointers to the pbuf and netif struct. These are already pointers and do not need to be assigned to your wrapper struct using the address of operator (&): by doing so you are getting the memory location of the pointer itself. That is why it is complaining about not being able to convert pbuf** to pbuf*.
Solution
local_w_p_n->wp_val_p = &rx_pbuf; to local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = &rx_netif; to local_w_p_n->wp_val_n = rx_netif;
Here in the function params,
struct pbuf *rx_pbuf, struct netif *rx_netif
Are already pointers, you do not need to get the address of the pointers, the & is useful when your variables are allocated on the stack and the function call needs a pointer.
As a result, this is the code change
local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = rx_netif;
In the original posted code local_w_p_n was defined as a pointer but not initialized; the attempts to assign members should crash since local_w_p_n would be leftover stack data, not a valid address. Try this example:
void rx_local_p_n(struct pbuf *rx_pbuf, struct netif *rx_netif)
{
// define as a struct instead of a struct *
struct wrapper_p_n local_w_p_n;
// assign from func args without &
// switch from -> to .
local_w_p_n.wp_val_p = rx_pbuf;
local_w_p_n.wp_val_n = rx_netif;
x_function(&local_w_p_n);
}

Segfault on copying struct

I have a struct as following:
extern struct team_t
{
char *name1;
char *email1;
char *name2;
char *email2;
} team;
struct team_t team =
{
"some string1",
"some string2",
"some string3",
"some string4"
};
Then in another file I create the following function that copies this struct into a new struct:
void *ucase( struct team_t *team)
{
struct team_t *ucase_team = malloc( sizeof *ucase_team);
memcpy ((char*)ucase_team, (char *)team, sizeof (ucase_team));
return NULL;
}
However, when I want to call ucase(team), I'm getting a segfault. I need to use void * because this will later be used for shell signals. What am I missing?
Update: Following call gives type argument of unary ‘*’ (have ‘struct team_t’) error:
ucase(*team)
Update 2: I have removed Null return and used ucase(team) but still getting segfault.
The last argument of memcpy() should be sizeof(struct team_t) instead of sizeof (ucase_team) as ucase_team is a struct pointer variable. It can be either sizeof(*ucase_team) or sizeof(struct team_t).
Also calling team() function like
ucase(*team);
is wrong as team is not a variable of pointer type, it's a normal structure variable. Probably you want
ucase(&team);

Dynamic struct in C

I am trying to read the inputed name, save it in a dynamic struct, add a number at the end if it and count it up. I managed to do the first part, but i cant seem to pass the struct address to the function that should count, nor make the function work.
struct ime_dadoteke
{
unsigned char *ime;
unsigned char velikost;
//this is the struct im working with
};
This is the main:
struct ime_dadoteke *ime;
ime = ime_init();
int i=1;
do
{
naslednje_ime(ime, i); /*here is the problem with passing the
address. I also tried &ime with parameter
struct ime_dodoteke **ptr.
I get error cannot convert argument 1
from 'ime_dadoteke *' to 'ime_dodoteke *' */
i++;
} while (i <= st_korakov);
This is the first function which works:
struct ime_dadoteke* ime_init()
{
int i;
struct ime_dadoteke *rtn = (struct ime_dadoteke*)malloc(sizeof(struct ime_dadoteke));
printf_s("Vnesi ime slike.\n");
rtn->ime =(unsigned char*)malloc(sizeof(unsigned char));
for (i=0; rtn->ime[i-1]!=10; i++)
{
scanf("%c", &rtn->ime[i]);
rtn->ime = (unsigned char*)realloc(rtn->ime, (i+2)*sizeof(unsigned char));
};
rtn->ime[i]='\0';
rtn->velikost = i;
fseek(stdin, 0, SEEK_END);
return rtn;
};
And this is the skeleton of the function that should count the number at the end of the name. I didnt build it yet because i get a problem: pointer to incomplete class is not allowed.
void naslednje_ime(struct ime_dodoteke *ptr, int i)
{
struct ime_dadoteke *ime = ptr;
ptr /*ptr is underlined (error) */->ime[ptr /*ptr is underlined (error) */->velikost - 1] = '0';
};
Also note i created the struct with size of string in it because strlen() doesnt wanna take a non const char. Is there a way around this?
The error message pointer to incomplete class is not allowed means the structure (you told us that referencing members of the struct ime_dadoteke via pointer struct ime_dadoteke *ptr caused the error message) is not defined in the source unit where naslednje_ime is defined. You need to put the struct definition in a header file and include it wherever you use it, also in the file where you define naslednje_ime.

Initialize structs issues on C

I'm getting this error during compilation:
"c:\command_line.h(17): error C2143: syntax error : missing ';' before '*'
Note: C++ does not support default-int
command_line.h(17): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int"
This my code:
command_line.h
typedef struct symbol
{
char* sym_type;
unsigned short address;
}symbol;
typedef struct symbol_map
{
char** p_arr_keys;
symbol* p_arr_values;
int item_count;
int array_mode;
int copy_keys;
}symbol_map;
typedef struct params
{
int data_counter;
int code_counter;
int line_counter;
int command_len;
int error_counter;
int warning_counter;
symbol_map* p_symbol_map; // (This is line 17- from the error msg)
char* p_last_symbol
}params;
main.c
params config;
config.code_counter = 0;
config.data_counter = 0;
config.line_counter = 0;
config.command_len = 0;
config.command_first_char = EMPTY;
config.error_counter = 0;
config.warning_counter = 0;
config.p_last_symbol = NULL;
config.p_symbol_map = {NULL}; // (This is line 17- from the error msg)
Any idea what's wrong with this initialization?
config.p_symbol_map = {NULL};
A construct you have used config.p_symbol_map = {NULL} is a static initialization and is only allowed in a variable declaration. If you want to assign a NULL to p_symbol_map you can simply config.p_symbol_map = NULL.
A valid case for static initialization applied to a symbol structure would be something like this:
symbol sym = {
NULL,
0x42
};
updated:
Btw, you are missing a semicolon after char* p_last_symbol in a structure definition.
typedef struct params
{
int data_counter;
int
int line_counter;
int command_len;
int error_counter;
int warning_counter;
symbol_map* p_symbol_map; // (This is line 17- from the error msg)
char* p_last_symbol <----- need to add ; here
}params;
You are not initializing a structure, you are initializing a pointer to a structure.
struct foo {
int a;
int b;
};
struct foo bar = {.a = 0, .b = 1};
But if you are declaring a pointer to it, then you don't have a memory block to initialize at first. So you can't use {} idiom to initialize a pointer to struct;
struct foo *bar;
bar = NULL
Something is wrong there, you are assigning to p_last_symbol member which you didn't declare in params. Also, p_symbol_map is a pointer to something, you can either initialize it with NULL or make it point to something else (such as memory allocated with malloc).
There is no need for {} around NULL. Just using NULL or nullptr would do. Further, what is p_symbol_map? There is no such thing in your declaration of params.
Also, in line 17, it should be wrtten as:
struct symbol_map* p_symbol_map. This is the reason there is an error on line 17.
Hope this helped.
You cant do it like that. You have to initialize the config AFAIK. You can do this since you are assigning a pointer and not a struct.
config.p_symbol_map = NULL;

Passing a struct into a generic function in C

I declare a new struct with the name of "Struct"
I have a generic function that takes in an argument "void *data".
void Foo(void *data)
I pass an instance of "Struct" into the generic function.
Struct s;
Foo(&s);
I want to access one of the properties of the struct in the function.
void Foo(void *data) {
char *word = (char*) data.word;
}
It's not allowed because it doesn't recognize data as a valid struct.
I even try to declare the data as the struct type first, and I get an error.
void Foo(void *data) {
Struct s = (Struct) data;
char *word = s.word;
}
I get "conversion to non-scalar type requested".
First of all, you should turn on your compiler's warning flags (all of them). Then you should pass a pointer to your Struct and use something other than struct as a variable name:
Struct s;
Foo(&s);
Then, in Foo:
void Foo(void *data) {
Struct *s = data;
char *word = s->word;
}
You can't convert non-pointer types to and from void* like you're trying to, converting pointer types to and from void* is, on the other hand, valid.
You need to pass a pointer to you struct and get a pointer to the struct inside the function:
Struct struct;
Foo(&struct);
void Foo(void *data) {
Struct* struct = (Struct*) data;
char *word = struct->word;
}
You have to use -> operator when requesting structure member via pointer.
This should work: char *word = (char*) data->word;
You also have to pass the address of the structure to the function. Like this: Foo(&struct);.
Firstly you need to call the function correctly:
Struct s;
Foo(&s);
Notice you're now passing a pointer to the structure.
Now, the function has to know that you're using a Struct (as opposed to something else) - perhaps because of another parameter, or a global variable, or some other reason. Then inside the function you can do:
void Foo(void *data) {
Struct *structpointer = p; /* Note - no need for a cast here */
/* (determine whether data does refer to a pointer then...) */
char *word = structpointer->word;
/* ... then use 'word'... */
}
Data is pointer, so whatever you cast it to must also be a pointer. If you said Struct* myStruct = (Struct*) data, all would be well with the world.
You are mixing pointers and data.
Struct struct defines a data object
void *data expects data to be a pointer.
Call Foo with a pointer to a Struct, and make other necessary changes
Struct struct;
Foo((void*)&struct);
void Foo(void *data) {
Struct *struct = (Struct*)data;
char *word = struct->word;
}
or the more compact form:
Struct struct;
Foo((void*)&struct);
void Foo(void *data) {
char *word = ((Struct*)data)->word;
}

Resources