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

XInitThreads引发内存泄漏,如何主动释放其分配的内存?

问题:XInitThreads分配的内存无法主动释放?

我在用minilibx(X11的封装库),为了让库支持线程,我在初始化函数里加了XInitThreads()。编译出的程序叫fdf,用Valgrind(命令:valgrind --log-file=v.log --leak-check=full ./fdf test2.fdf)检测内存泄漏时,发现XInitThreads分配的内存没被释放。有没有主动释放这块内存的方法?程序结束时需要调用什么函数来释放XInitThreads分配的内存?

系统信息(Ubuntu)

Linux 6.11.0-1-t2-jammy #1 SMP PREEMPT_DYNAMIC Tue Sep 17 06:47:39 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Valgrind日志(v.log)

==1546656== Memcheck, a memory error detector
==1546656== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1546656== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1546656== Command: ./fdf test2.fdf
==1546656== Parent PID: 1464122
==1546656== 
==1546656== 
==1546656== HEAP SUMMARY:
==1546656==     in use at exit: 120 bytes in 3 blocks
==1546656==   total heap usage: 53,837 allocs, 53,834 frees, 1,199,360 bytes allocated
==1546656== 
==1546656== 40 bytes in 1 blocks are still reachable in loss record 1 of 3
==1546656==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1546656==    by 0x48B09E9: XInitThreads (in /usr/lib/x86_64-linux-gnu/libX11.so.6.4.0)
==1546656==    by 0x11422A: mlx_init (in /home/baschnit/repos/42fdf_new/fdf)
==1546656==    by 0x10AAB1: main (main.c:59)
==1546656== 
==1546656== 40 bytes in 1 blocks are still reachable in loss record 2 of 3
==1546656==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1546656==    by 0x48B0A06: XInitThreads (in /usr/lib/x86_64-linux-gnu/libX11.so.6.4.0)
==1546656==    by 0x11422A: mlx_init (in /home/baschnit/repos/42fdf_new/fdf)
==1546656==    by 0x10AAB1: main (main.c:59)
==1546656== 
==1546656== 40 bytes in 1 blocks are still reachable in loss record 3 of 3
==1546656==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1546656==    by 0x48B0A23: XInitThreads (in /usr/lib/x86_64-linux-gnu/libX11.so.6.4.0)
==1546656==    by 0x11422A: mlx_init (in /home/baschnit/repos/42fdf_new/fdf)
==1546656==    by 0x10AAB1: main (main.c:59)
==1546656== 
==1546656== LEAK SUMMARY:
==1546656==    definitely lost: 0 bytes in 0 blocks
==1546656==    indirectly lost: 0 bytes in 0 blocks
==1546656==      possibly lost: 0 bytes in 0 blocks
==1546656==    still reachable: 120 bytes in 3 blocks
==1546656==         suppressed: 0 bytes in 0 blocks
==1546656== 
==1546656== For lists of detected and suppressed errors, rerun with: -s
==1546656== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

最小复现步骤

  • 从Git下载minilibx到libx文件夹
  • 在父文件夹创建main.c文件,用命令编译:cc main.c libx/libmlx.a -Ilibx -lX11 -lXext
  • 执行检测:valgrind --leak-check=full --show-leak-kinds=all ./a.out

main.c代码

#include <stdlib.h>
#include <X11/Xlib.h>
#include "mlx.h"

int main(void)
{
    void *mlx;

    XInitThreads();
    mlx = mlx_init();
    mlx_destroy_display(mlx);
    free(mlx);
}

解答

首先明确:X11没有提供官方函数来释放XInitThreads()分配的内存。

从Valgrind日志能看到,这些内存标记为still reachable,意味着程序退出时内存是可访问的,但没有被主动释放。这类内存通常会由操作系统在进程终止后自动回收,不属于严重的内存泄漏问题。

为什么没有释放函数?

XInitThreads()初始化的是Xlib的全局线程安全结构,这些结构设计为在整个进程生命周期中存在,X11库本身不会提供销毁接口——因为一旦启用线程支持,进程中所有Xlib操作都依赖这些结构,直到进程结束。

怎么处理Valgrind的报告?

如果不想看到这些报告,有两个方案:

  1. 忽略still reachable类型的泄漏:这类泄漏不会导致内存增长,进程结束后系统会回收,对程序运行没有影响。
  2. 添加Valgrind抑制规则:创建一个抑制文件,让Valgrind忽略XInitThreads相关的内存分配。示例抑制规则如下:
    {
       <XInitThreads_leak>
       Memcheck:Leak
       match-leak-kinds: reachable
       fun:malloc
       fun:XInitThreads
    }
    
    保存为xinitthr.supp,然后运行Valgrind时加上--suppressions=xinitthr.supp参数即可。

注意事项

不要尝试手动释放这些内存——你没有办法安全获取这些内存的指针,强行释放会导致程序崩溃或未定义行为。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:17:05