Search code examples
cpthreadspthread-join

How to use a struct pointer returned to the in the main from a thread function?


I am writing a program that takes integers as command line arguments. For each of these numbers I have to create a thread which calculates Fibonacci series up to that number. That function returns a struct pointer to the main where the data is printed.

Now, I have correctly done the fib calculations and checked them by printing the series within the function.

The problem arises when I try to return the struct pointer created within the thread function and use it to print the data in the main.

typedef struct thread_func_param
{
    int *fib;
    int size;
} thread_func_param;
//===================================================    
void *fibGen(void *parameters)
{
    int num = atoi(parameters);
    struct thread_func_param *p;
    p = malloc (sizeof (thread_func_param));

    p->size = fibSize(num);
    p->fib = malloc(sizeof(int)* p->size);

    //Fibonacci Calculations
    //..
    //.

    return (void *) p;
    //pthread_exit((void *) p);
}
//=================================================== 
int main(int argc, char* argv[])
{
    void* thread_result;
    thread_func_param* p = malloc( sizeof(thread_func_param));
    assert(argc > 1);

    int noOfThreads = argc - 1;
    printf("No of Thread = %d\n", noOfThreads);
    pthread_t *threadID = malloc (sizeof (pthread_t) * noOfThreads);

    pthread_attr_t attributes;
    pthread_attr_init(&attributes);

    int i, j;
    for(i = 0; i < noOfThreads; i++)
    {
        pthread_create(&threadID[i], &attributes, fibGen, argv[i+1]);
        pthread_join(threadID[i], thread_result);


        //HOW TO USE THE RETURNED DATA?
        for (j = 0; j< ((thread_func_param*)thread_result->size)-1; j++)
        printf(" %d ", (thread_func_param*)thread_result->fib[j]);
    }

    return 0;
}

The solution that I use, in the end, to print the data gives error of dereferencing a void pointer (I am new with C). How can I correct it?


Solution

  • Two issues here:

    1. pthread_join() takes a void** as 2nd parameter. The code passes a void* only.
    2. To cast a pointer wrap it into parenthesis. Here the cast

      (thread_func_param*)thread_result->size
      

      refers to size not to thread_result. So what you want is

      ((thread_func_param*)thread_result)->size
      

    However a nice and clean solution would only use a void pointer interimswise. It could look like this:

    int main(int argc, char* argv[])
    {
      thread_func_param* thread_result;
    
      ...
    
        ...
    
        pthread_create(&threadID[i], &attributes, fibGen, argv[i+1]);
    
        {
          void * pv; 
          pthread_join(threadID[i], &pv);
          thread_result = pv;
        }
    
        if (NULL != thread_result) /* perform some sanity checking. */
        {
          for (j = 0; j < thread_result->size - 1; j++)
            printf(" %d ", thread_result->fib[j]);
        }
    
        ...