简体   繁体   中英

Trying to pass an instance of a struct to a thread function with an integer and a double value

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM