Reputation: 104
As far as I know, malloc()
(or any heap allocation function) and free()
must be paired. I thought it is the same in the multi-threaded programs. But it looks like I should not free()
a heap variable that was allocated at another thread.
When I run the code below (in wsl ubuntu environment),
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void* thread_main(void* arg) {
int i = 0;
for (; i < *((int*)arg); i++) {
printf("thread running... %d\n", i);
}
char* msg = (char*)malloc(sizeof(char) * 50);
msg = "thread end\n";
return (void*)msg;
}
int main() {
pthread_t thread_id;
int thread_arg = 5;
void* thread_return;
pthread_create(&thread_id, NULL, thread_main, (void*)&thread_arg);
pthread_join(thread_id, &thread_return);
printf("thread returned message : %s", (char*)thread_return);
free(thread_return); // if I comment out this line, the program succeeds.
return 0;
}
I get an std output of
thread running... 0
thread running... 1
thread running... 2
thread running... 3
thread running... 4
thread returned message : thread end
munmap_chunk(): invalid pointer
Aborted (core dumped)
However, if I comment out free(thread_return);
part, the program succeeds and does not produce the aborting error dump message.
So, is there no need to free the heap variable created from another thread? Or even more, is it wrong to free the heap variable if it was created from another thread?
Upvotes: 0
Views: 1038
Reputation: 536
In Short
Always free allocated memory in the same logical unit that allocated it.
Reasoning
If you free memory that was allocated on another thread, or even say a dynamically allocated buffer you received as a parameter to your function, which you decide to free - you can cause a lot of problems.
Future use of this variable can cause your program to crash since it tried getting to unallocated memory.
It's really a best practice to do as i wrote in the summary, especially when writing code for bigger projects with multiple developers - since you can't always know what will happen in the future of the dynamically allocated buffer.
The Crash
Addressing your crash, it isn't caused by you trying to free memory allocated on another thread - it simply happens since by using the line:
msg = "thread end\n";
right after allocating the memory and assigning it to msg, you lost your pointer to the allocated memory. Now when freeing "msg" you are trying to free a variable allocated on the stack.
Upvotes: 0
Reputation:
char* msg = (char*)malloc(sizeof(char) * 50);
msg = "thread end\n";
The second line here overwrites the pointer allocated by malloc()
with a pointer to a constant string, causing the memory that was originally allocated to be leaked. The value returned by this thread points to that constant string, not the memory allocated by malloc()
; attempting to free()
that value will fail, because it was not allocated by malloc()
.
Use strncpy()
to write a string to the memory allocated by malloc()
. Once you've done that, you can (and should) deallocate the resulting memory with free()
in the main thread.
Upvotes: 2