Reputation: 2413
I am trying to pass a struct as a parameter to pthread_create and seem to be getting some strange results.
The struct has two members, first one being an int and the second one is a function pointer:
typedef struct
{
int num;
void (*func)(int);
} foo_t;
The function I am trying to use within the struct:
void myfunc(int mynum)
{
printf("mynum: %d\n", mynum);
}
This is the declaration of the struct I will be passing to my thread:
foo_t f;
f.num = 42;
f.func = &myfunc;
The call to pthread_create:
pthread_create(&mythread, NULL, mythreadfunc, &f);
And finally, my thread function:
void mythreadfunc(void *foo)
{
foo_t f = *(foo_t *)foo;
printf("num: %d\n", f.num); // Prints: num: 32776 (undefined?)
(*f.func)(f.num); // Segfaults (again, undefined?)
...
It seems that the cast within mythreadfunc doesn't seem to work and I can't figure out why. Any suggestions? Thanks.
Upvotes: 0
Views: 787
Reputation: 1323
You are passing your foo_t f
by reference. If you are changing your f
from your pthread_create
-calling function or somewhere else, for example leaving the corresponding scope would remove/delete f
from the stack, then your reference inside your thread is (most likely) invalid. At least you should not access it anymore.
Use pointers with dynamically allocated variables instead.
Though I can not prove that this is happening with the code you have presented.
Edit:
A pointer is used to store the address of an object/variable. In C/C++
you can have it point to a dynamically allocated memory segment. Look up malloc/
new
for this. You can do what is called dereferencing
with pointers and access the objecct/variable itself.
You can pass the pointer per value, which means, that you won't pass the object/variable itself, but the address(= position) of the object/variable inside your RAM. The memory management of dynamically allocated varialbes/object lies in the responsibility of the programmer, so your object won't be deleted when the scope of the pointer ends, only the pointer which stores the address will be deleted.
Upvotes: 1
Reputation: 215193
Papergay's answer is definitely one solution, but another approach you can use if you want to avoid dynamic allocation is just using synchronization. My favorite approach is putting a semaphore with initial-value zero in the struct and having the parent wait on the semaphore and the child post the semaphore after it's done reading the values out of the structure.
Upvotes: 1