pitachips
pitachips

Reputation: 104

Is there no need to free() a heap variable allocated and returned from a thread?

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

Answers (2)

YMeC
YMeC

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

user149341
user149341

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

Related Questions