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的报告?
如果不想看到这些报告,有两个方案:
- 忽略
still reachable类型的泄漏:这类泄漏不会导致内存增长,进程结束后系统会回收,对程序运行没有影响。 - 添加Valgrind抑制规则:创建一个抑制文件,让Valgrind忽略
XInitThreads相关的内存分配。示例抑制规则如下:
保存为{ <XInitThreads_leak> Memcheck:Leak match-leak-kinds: reachable fun:malloc fun:XInitThreads }xinitthr.supp,然后运行Valgrind时加上--suppressions=xinitthr.supp参数即可。
注意事项
不要尝试手动释放这些内存——你没有办法安全获取这些内存的指针,强行释放会导致程序崩溃或未定义行为。
内容的提问来源于stack exchange,提问作者Bastian
相关产品推荐
相关产品推荐

