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

XLib加载特定字体字符串时出现内存泄漏问题求助

XLoadQueryFont加载部分字体出现Valgrind内存泄漏的解决方法

当使用XLib的XLoadQueryFont加载"fixed"字体时无内存泄漏,但加载通配符匹配的字体(如"-adobe-*-*-*-*-*-14-*-*-*-*-*-*-*"、"*-*-*-*-*-*-14-*-*-*-*-*-*-*"等)时,程序运行正常但Valgrind会检测到内存泄漏。

问题复现代码

#include <X11/Xlib.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

void main()
{
  Display* display;
  XFontStruct* font_info;
  char* font_name = "*-helvetica-*-12-*";
//  char *font_name = "fixed";

  display = XOpenDisplay(getenv("DISPLAY"));
  if (display == NULL) {
    fprintf(stderr, "cannot connect to X server\n");
    exit(1);
  }

  font_info = XLoadQueryFont(display, font_name);
  if (!font_info) {
      fprintf(stderr, "XLoadQueryFont: failed loading font '%s'\n", font_name);
      exit(-1);
  }

  XFreeFont(display, font_info);
  XCloseDisplay(display);
}

泄漏原因

使用通配符字体名称时,X服务器会先加载多个候选字体进行匹配,最终仅返回最优匹配的字体给客户端,但这些临时加载的候选字体资源不会被自动释放。而"fixed"是精确匹配的内置字体,无需多候选匹配流程,因此没有额外内存残留。XFreeFont仅释放返回给你的XFontStruct关联资源,无法清理X服务器匹配过程中产生的临时资源。

解决办法

  1. 使用精确字体名称
    先通过XListFonts获取匹配通配符的所有精确字体名称,再选择其中一个调用XLoadQueryFont,避免通配符匹配带来的临时资源泄漏:

    char **fonts;
    int num_fonts;
    // 查询匹配通配符的字体列表,最多返回100个
    fonts = XListFonts(display, "*-helvetica-*-12-*", 100, &num_fonts);
    if (fonts && num_fonts > 0) {
        font_info = XLoadQueryFont(display, fonts[0]);
        XFreeFontNames(fonts); // 释放字体名称列表资源
    }
    
  2. 强制同步X服务器资源
    在关闭显示连接前调用XSync(display, True),强制X服务器处理未完成的资源释放操作,但这种方法无法保证完全清理所有临时匹配资源,仅作为补充手段:

    XFreeFont(display, font_info);
    XSync(display, True); // 同步资源清理
    XCloseDisplay(display);
    
  3. 忽略Valgrind误报(不推荐)
    若确认泄漏为X服务器临时资源且不会累积,可在Valgrind配置中添加规则忽略此类报告,但这可能掩盖真正的内存问题,不建议长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:03:10