You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

线程分配的堆变量无需free?跨线程调用free()为何报错?

问题分析:你的错误不是跨线程释放,而是指针被覆盖了!

嘿,先别误会跨线程释放的问题,咱们先揪出你代码里的关键bug:

看你子线程里的这段代码:

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

你先用malloc在堆上申请了一块内存,但是紧接着直接把msg的指针指向了字符串字面量"thread end\n"——这个字面量是存在进程的只读数据段里的,根本不是你刚malloc出来的堆内存!

这就导致你最后返回给主线程的thread_return,其实是一个只读常量的地址,而不是堆内存的地址。这时候你调用free(thread_return),相当于尝试释放只读数据段的内容,系统当然会报错munmap_chunk(): invalid pointer,因为free只能用来释放堆上的内存。


关于跨线程释放堆内存的说明

其实在POSIX标准(包括你用的WSL Ubuntu环境)中,跨线程释放堆内存是完全合法的操作!堆是进程级别的共享资源,所有线程共享同一个堆空间,只要你要释放的指针是合法的(由malloc/calloc/realloc分配的堆地址),不管这个指针是哪个线程分配的,都可以在任意线程里调用free来释放,完全没问题。


修正后的代码示例

把字符串复制到malloc的堆内存里,而不是直接赋值指针就可以解决问题:

#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);
    strcpy(msg, "thread end\n"); // 用strcpy把字符串复制到堆内存中
    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); // 现在可以正常释放了!
    return 0;
}

这样修改后,主线程释放子线程分配的堆内存就不会报错了。

内容的提问来源于stack exchange,提问作者pitachips

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:04:03