Pass a struct to pthread_create's startup routine - c

So I've got an assignment that I'm having trouble with. I'm trying use pthreads to sum the elements of a matrix with 3 different processors. I have a struct
typedef struct{
int rows;
int cols;
pid;
int localsum;
}ThreadData;
some global variabls
int processors=3;
int rows=4;
int cols=4;
int matrix[10][10];
and a sum function
void *matrixSum(void *p){
//cast *a to struct ThreadData?
int sum=0;
int i=p->pid;
int size=p->rows*p->cols;
//to sequentially add a processor's 'owned' cells
int row=p-pid/p-cols;
int col=p-pid%p->cols;
int max_partition_size = ((size/processors)+1);
for(i;i<max_partition_size*processors;i+=processors){
col=i%p->cols;
row=i/p->cols;
if(i<=size-1){
sum+=matrix[row][col]+1;
}
}
p->localsum=sum;
}
so my main method looks like this:
int main(){
int totalsum=0;
ThreadData *a;
a=malloc(processors*(sizeof(ThreadData));
int i;
for(i=0;i<processors;i++){
a[i].rows=rows;
a[i].cols=cols;
a[i].pid=i;
a[i].localsum=0;
}
//just a function that iterates over the matrix to assign it some contents
fillmatrix(rows, cols);
pthread_t tid[processors];
for(i=0;i<processors;i++){
pthread_create(tid,NULL,matrixSum,(void *)&a);
totalsum+=a[i].localsum;
}
pthread_join();
}
My ultimate goal is to pass my matrixSum() with a ThreadData struct as the argument.
So I think I have to cast the void pointer given in matrixSum() to a struct, but I'm having trouble doing so.
I tried doing so like this
ThreadData *a=malloc(sizeof(ThreadData));
a=(struct ThreadData*)p;
But I get a warning: assignment from incompatible pointer type error.
So what's the proper way to do this - that is to cast the void pointer taken from the parameters, and operate on it like the struct it is meant to be?

Try using a=(ThreadData*)p;.
In C language, struct ThreadData is differ to ThreadData.
In this case, you used typedef and defined no tag to the struct, so you mustn't use struct to use the struct.

Related

Initiliazing int array with pointer type variable

I have the following code.
FlowNProcess f1[3];
int f1resources[2]={-1,0};
f1[1].resoures =f1resources;
typedef struct FlowNProcess
{
int id;
int tt;
int wt;
Requirement *requirement;
int *resoures;
char *state;
} FlowNProcess;
Here since the resources is an int* so, I am first creating an array of size 2 and then
assigning the pointer to it. Is there a better way to achieve the same, maybe a one-liner

How to access element of unknown struct by pos?

In the main program, I have many different structures and associated types, and I call an external function that I keep in a separated dll:
typedef struct{int a; int b; int c; int d;} t1;
typedef struct{int x; int y; double z; double w;} t2;
// ...
int ret;
char* s="blah";
t1* parms1;
t2* parms2;
ret=MyFunc(s, t1);
//...
ret=MyFunc(s, t2);
In the dll, the above types are neither defined nor known, and I have the following function:
__declspec(dllexport) int MyFunc(char* pstmt, void* pRS){
//--
}
My question is, is there a way to access (i.e. read/set) the passed struct elements inside the dll? Like, position-based access or something like that? For instance, I would like to be able to write something like:
pRS->*<either a or x>*=*<something>*
you have to cast the (void*) to any wanted struct as in your case:
((t1*)pRS)->a=0;
or
((t2*)pRS)->x=0;

dynamically allocating an int array inside a structure

I'm trying to dynamically create an array of ints for grades that are inside of a structure but I have a small syntax error. Here is my code:
typedef struct
{
int Stud_ID;
int class_ID;
int* Grades;
int Grade_Cap;
int Count;
float Average;
}enrollment;
typedef struct
{
int Enrollment_Count;
int Enrollment_Cap;
enrollment *enrollment_list;
}enrollments;
void add_grade_space(enrollments *enroll)
{
enroll->enrollment_list[enroll->Enrollment_Count].Grade_Cap = malloc(sizeof(int)*2);
}
The error I get says: assignment makes integer from pointer without cast.
enroll->enrollment_list[enroll->Enrollment_Count].Grade_Cap = malloc(sizeof(int)*2);
You are trying to allocate memory to Grade_Cap which is not a pointer . It is an integer variable .You need to declare it as int * to allocate memory if you want to.

Deferencing Void Pointer in c

i'm having troubles trying to deference a void pointer in C.
Well, i make a linked list that have a "Nodo" with a void* info, that's because info will change of type.
typedef struct nodo
{
void *info; //This'll change types, like different structs.
char label; // S si es un switch, E si es un enemigo
struct nodo *siguiente;
}tNodo;
typedef struct Lista {
tNodo *head;
tNodo *tail;
tNodo *curr;
unsigned int listSize;
unsigned int pos;
}tLista;
Here's my struct tEnemigo, this'll be one of the struct that info could take.
typedef struct
{
char(*siguiente_movimiento)(void *,char **,int,int);
char tipo;
int maxmov;
int pasos;
char direccion;
int y;
int x;
}tEnemigo;
In this function i just pass void *general to take the info of it
char movEnemigos(tLista *listaEnemigos, char **map)
{
void *general;
general = &listaEnemigos->curr->info; //A struct
siguiente_movimiento(general, map , x, y);
}
And here's my problem, i can't give the "info" that is located general, i read something about cast the void pointer, but i failed miserably.
char siguiente_movimiento(void *general, char **map, int x, int y)
{
tEnemigo *enemigo;
enemigo = *(tEnemigo *) general ;
}
I don't know how to do this, maybe i'm wrong with all my "idea" of the code...hope you guys can give me a hand.
EDIT: THIS IS THE ERROR CODE.
error: incompatible types when assigning to type ‘tEnemigo’ from type ‘struct tEnemigo *’
*(tEnemigo *) general = enemigo;
In your siguiente_movimiento function, enemigo is a pointer, but you are trying to assign a value to it that is not a pointer (because you dereference it with *). Your function should look like this:
char siguiente_movimiento(void *general, char **map, int x, int y)
{
tEnemigo enemigo;
enemigo = *(tEnemigo *) general ;
}
Or:
char siguiente_movimiento(void *general, char **map, int x, int y)
{
tEnemigo *enemigo;
enemigo = (tEnemigo *) general ;
}
You currently have a mix of the two.
The error message gives the game away — you haven't declared a type struct tEnemigo.
You have:
typedef struct
{
...
}tEnemigo;
You either need to drop the struct when using the type, or you need:
typedef struct tEnemigo
{
...
} tEnemigo;
Both techniques work. I'd probably add the tag anyway, but I'd definitely write the code in terms of the typedef name (just tEnemigo), not struct tEnemigo.
And, as a side note, you should aim to avoid void * arguments. One advantage of the struct tEnemigo tag is that you can define opaque types by simply saying:
struct tEnemigo; // There is a type struct tEnemigo...
char siguiente_movimiento(struct tEnemigo *enemigo, char **map, int x, int y);
Your code that uses struct tEnemigo pointers does not need to know about the internals of the structure; only code that needs to look inside the structure needs to know the full type definition.
One reason for avoiding void * arguments is that any pointer type can be passed to a function that expects a void *. For example, if you have a FILE *fp = fopen("something", "r);, then the compiler cannot diagnose an error in:
char c = siguiente_movimiento(fp, map, 1, 3);
even though it is clearly a mistake. With the struct tEnemigo * declaration for the function, this mistake becomes a compilation error.
Rule of Thumb: if the void * argument only maps to a single type, then the chances are good that the function shouldn't be written with a void * argument. (There are exceptions: for example, if you have a family of functions called by function pointer, you might need a void * argument so that a single call can call any of the functions. Memory allocation functions are another special case.)

C Function Prototype With Struct Argument

I want to write a function prototype for a function, whose argument is a pointer to a struct.
int mult(struct Numbers *n)
However, the struct Numbers, which is defined as
struct Numbers {
int a;
int b;
int c;
};
is not defined yet. How should I write a suitable prototype for mult?
Just declare struct Numbers as an incomplete type before your function declaration:
struct Numbers;
int mult(struct Numbers *n);
You must forward the declaration of the structure to tell the compiler that a struct with that name will be defined:
struct Numbers;
int mult(struct Numbers *n) {
}
struct Numbers {
int a;
int b;
int c;
};
Mind that the compiler is not able to determine the size in memory of the structure so you can't pass it by value.

Resources