I'm trying to pass an instance of a structure to a thread but for some reason it is printing a random value for the integer but the correct value of the double?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//Pass an integer value and a double value to a thread (use struct!)
typedef struct param {
int val;
double db;
}param_t;
void *myth(void *arg)
{
param_t myT, *myPt;
myT = *((param_t*)arg);
myPt = (param_t*)arg;
printf("%d\n", myT.val);
printf("%.3lf\n", myPt->db);
pthread_exit(NULL);
}
void main()
{
pthread_t tid;
int i = 3733;
double d = 3733.001;
param_t t_struct;
param_t *p;
p = malloc(sizeof(param_t));
*p = t_struct;
t_struct.val = i;
t_struct.db = d;
pthread_create(&tid, NULL, myth, (void *)&p);
pthread_join(tid, NULL);
return;
}
Output: 10969104 3733.001
One problem is here:
*p = t_struct;
t_struct.val = i;
t_struct.db = d;
The first assignment copies the uninitialized structure t_struct
. Then you initialize t_struct
, but that only initializes t_struct
itself. It doesn't modify the copy pointed to by p
.
Then you make it even worse by passing a pointer to the pointer. That means inside the thread function myth
the argument arg
doesn't point to a structure at all. Which leads to undefined behavior when you dereference the pointer.
My recommendation is to not bother with p
or the dynamic allocacion at all. Instead pass a pointer to the original structure t_struct
:
pthread_create(&tid, NULL, myth, & t_struct);
This makes no sense:
param_t t_struct;
param_t *p;
p = malloc(sizeof(param_t));
*p = t_struct; // t_struct isn't initialized, so this is undefined behaviour.
t_struct.val = i; // Has no effect on `p` or `*p`.
t_struct.db = d; // Has no effect on `p` or `*p`.
Maybe you were going for
param_t t_struct;
param_t *p;
p = malloc(sizeof(param_t));
t_struct.val = i;
t_struct.db = d;
*p = t_struct;
The following would be better:
param_t t_struct;
t_struct.val = i;
t_struct.db = d;
param_t *p = &t_struct;
You can also use the following:
param_t *p = malloc(sizeof(param_t));
p->val = i;
p->db = d;
Unlike the previous solution, this last solution doesn't require t_struct
to keep existing until the thread is joined
There's a second problem.
arg
is really a param_t **
, but you treat it as a param_t *
.
Fixed:
void *myth(void *arg) // arg is really a param_t *
{
param_t *p = (param_t*)arg;;
printf("%d\n", p->val);
printf("%.3lf\n", p->db);
pthread_exit(NULL);
}
pthread_create(&tid, NULL, myth, p);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.