The answer is simple: you are passing a reference of a local variable and then leaving the scope. Replace it with data allocated on heap and it would work like a charm
void start_thread(pthread_t *mt)
{
mystruct *data = malloc(sizeof(*data));
...;
pthread_create(mt, NULL, do_work_son, data);
}
EDIT:
About preassignment question:
void start_thread(pthread_t *mt)
{
mystruct local_data = {...};
mystruct *data = malloc(sizeof(*data));
*data = local_data;
...;
pthread_create(mt, NULL, do_work_son, data);
}