I have done the following code.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
struct foo
{
int a;
int b;
};
void* thread_func1(void *arg)
{
struct foo *temp = (struct foo*)malloc(sizeof(struct foo));
temp->a = 10;
temp->b = 20;
pthread_exit(temp);
}
void* thread_func2(void *arg)
{
pthread_exit((void*)100);
}
int main()
{
pthread_t tid1, tid2;
int err;
struct foo *f;
void *ret;
err = pthread_create(&tid1, NULL, thread_func1, NULL);
err = err | pthread_create(&tid2, NULL, thread_func2, NULL);
if(err != 0)
{
perror("pthread_create()");
exit(-1);
}
err = pthread_join(tid1, (void**)&f);
if(err != 0 )
{
perror("pthread_join1");
exit(-1);
}
printf("a = %d, b = %d\n", f->a, f->b); //Line1
err = pthread_join(tid2, &ret);
if(err != 0 )
{
perror("pthread_join2");
exit(-1);
}
printf("ret = %d\n", *(int*)ret); //Line2
return 0;
}
I get segmentation fault on Line2. What is wrong with Line2
If i modify Line2 to
printf("ret = %d\n", (int)ret);
there is no segmentation fault and it prints the correct value(ie, 100). I do not understand why the modification works. I believe i have the wrong concept regarding the usage of double pointers. I would like to get it corrected.
What is the reason for the Segmentation fault and why the modification works?
You return one number from the thread. In the first thread, that number is a struct foo *
. Therefore, if you say
pthread_join(tid1, &ret);
then ret
will contain that pointer (which is not a double pointer).
Similarly in the second case, you are returning 100
even though you are looking at it as if it's a void *
. Nevertheless, the value is still 100
!
Therefore when you write
pthread_join(tid2, &ret);
ret
will contain 100
, which is not a pointer, but a mere integer. That is why you should also cast it to int
.
The reason you got a segmentation fault is that you look at 100
as an int *
and then try to dereference it.