不需要free()从线程分配和返回的堆变量吗?

时间:2019-06-09 09:28:11

标签: c multithreading heap

据我所知,malloc()(或任何堆分配函数)和free()必须配对。我认为在多线程程序中是相同的。但是看起来我不应该free()分配给另一个线程的堆变量。

当我在wsl ubuntu环境中运行以下代码时,

#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;
}

我得到标准输出

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)

但是,如果我注释掉free(thread_return);部分,程序将成功执行并且不会产生异常中止的错误转储消息。

那么,有没有必要释放从另一个线程创建的堆变量?甚至更多,如果它是从另一个线程创建的,则释放堆变量是否错误?

2 个答案:

答案 0 :(得分:2)

char* msg = (char*)malloc(sizeof(char) * 50);
msg = "thread end\n";

此处的第二行用指向常量字符串的指针覆盖malloc()分配的指针,从而导致最初分配的内存泄漏。该线程返回的值指向该常量字符串,而不是malloc()分配的内存;尝试free()的值将失败,因为malloc()并未分配该值。

使用strncpy()将字符串写入malloc()分配的内存中。完成此操作后,您可以(并且应该)在主线程中用free()释放结果内存。

答案 1 :(得分:-1)

简而言之

总是在分配它的同一逻辑单元中释放分配的内存。

理由

如果您释放在另一个线程上分配的内存,或者甚至说您决定将要动态释放的缓冲区作为函数的参数接收,而您决定将其释放,则会引起很多问题。

将来使用此变量可能会导致程序崩溃,因为它试图进入未分配的内存。

这确实是最佳实践,就像我在总结中所写的那样,尤其是在为具有多个开发人员的大型项目编写代码时-因为您始终无法知道动态分配的缓冲区的将来会发生什么。

崩溃

解决崩溃问题,不是由您试图释放分配给另一个线程的内存引起的,而是因为使用以下行而发生的:

msg = "thread end\n";

在分配内存并将其分配给msg之后,您丢失了指向已分配内存的指针。现在释放“ msg”时,您尝试释放分配在堆栈上的变量。