I have allocated heap
memory in the thread function f1
, this storage is used to calculate the value in the heap region so that the main function can see it.
Here is the thread function definition:
void *f1(void *input){
int sum = (int*)malloc(sizeof(int));
/* Do calculation */
pthread_exit((void*)&sum);
}
In the above code, the sum
is the heap allocated storage, whose address is passed as a return value to the sum1
in the main()
.
I join
the thread in the main()
like this:
void *sum1;
pthread_join(tid1,(void**)&sum1);
Once i retrieved the value, i want to free
the allocated memory.
When i use free
in the main, it complains like munmap_chunk(): invalid pointer
How can i explicitly and safely free
this memory ?
You should send back the pointer, not its address
pthread_exit(sum);
...
pthread_join(tid1, &sum1);
From the thread function you want to send back (with return
or pthread_exit()
) a pointer.
At pthread_join()
you want to obtain this pointer but the result of pthread_join()
is an integer to report success/failure.
Then we have to declare a pointer variable (sum1
here) to store the expected result and provide pthread_join()
with the address of this variable so that it could be updated (the same way we provide addresses to scanf()
in order to update the extracted variables).
The problem in your code is the use of casts. In C most of the time a pointer cast signifies an erroneous construct. Notably in this example no casts are required if the constructs are used correctly:
// no cast required because malloc returns void * and void * can be converted
// to a pointer to int without a cast
int *sum = malloc(sizeof (int));
// no cast required because int * can be converted to a void * without a cast
pthread_exit(sum);
void *sum1;
// no cast required because the address of void * is a void **!
pthread_join(tid1, &sum1);
The only place where you require a cast is if you now convert this void *
value to int *
inline:
int value = *(int *)sum1;
but you can convert it by assignment too, and then again, no cast is required:
int *value_ptr = sum1;
printf("The value was %d\n", *value_ptr);
free(value_ptr);
The rule of thumb is that a cast is OK if you know something better than a compiler - like "truncate this value to uint8_t
" or "this void pointer actually points to an int
, but I am not assigning it to one to save keystrokes" - but it is usually not OK just to silence a warning.
Some programmers write code like this:
int *ptr;
pthread_join(tid1, (void **)&ptr);
Such code is not strictly conforming as an int *
and void *
are not compatible types, may have or not have the same representation or even size, and especially may not alias each other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With