问题
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 ?
回答1:
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).
回答2:
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.
来源:https://stackoverflow.com/questions/56964745/how-to-free-memory-allocated-by-thread-function-in-the-main