Это потому что каждый раз
void pthread_exit(void *ret);
будет вызываться из потоковой функции, так что когда вы захотите просто вернуть ее указатель с помощью pthread_exit ().
Сейчас на
int pthread_join(pthread_t tid, void **ret);
всегда будет вызываться из того места, где создан поток, поэтому здесь, чтобы принять возвращенный указатель, вам нужно двойной указатель ..
я думаю, что этот код поможет вам понять это
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
void* thread_function(void *ignoredInThisExample)
{
char *a = malloc(10);
strcpy(a,"hello world");
pthread_exit((void*)a);
}
int main()
{
pthread_t thread_id;
char *b;
pthread_create (&thread_id, NULL,&thread_function, NULL);
pthread_join(thread_id,(void**)&b); //here we are reciving one pointer
value so to use that we need double pointer
printf("b is %s",b);
free(b); // lets free the memory
}