15

我无法创建一个在 valgrind 中没有超过 1K 的“肯定丢失”字节的 Qt GUI 应用程序。我已经对此进行了实验,制作了仅显示一个 QWidget 的最小应用程序,扩展了 QMainWindow;只是创建一个 QApplication 对象而不显示它或不执行它或两者兼而有之,但它们总是泄漏。

试图弄清楚这一点,我读到这是因为 X11 或 glibc 有错误,或者因为 valgrind 给出了误报。在一个论坛帖子中,似乎暗示在主函数中创建一个 QApplication 对象并返回对象的 exec() 函数,就像在教程中所做的那样,是制作 GUI 的一种“简化”方式(不一定很好, 也许?)。

valgrind 的输出确实提到了 libX11 和 libglibc,还有 libfontconfig。其余的内存丢失,5 条丢失记录,发生在??? in libQtCore.so期间QLibrary::setFileNameAndVersion

如果有一种更合适的方法来创建 GUI 应用程序,甚至可以防止其中的一部分发生,它是什么?如果任何 valgrind 输出只是噪音,我如何创建一个抑制文件来抑制正确的东西?

编辑:感谢您的评论和回答!
我并不担心自己丢失的几个 kB,但是如果我不必过滤多个错误屏幕但通常可以从 valgrind 获得“OK”,那么找到我自己的内存泄漏会更容易。如果我要抑制警告,我最好知道它们是什么,对吧?
有趣的是,看看泄漏是如何被接受的!

4

2 回答 2

20

大型多线程库(如 QT、wxWidgets、X11 等)设置单例类型对象的情况并不少见,这些对象在进程启动时初始化一次,然后不尝试清理进程关闭时分配。

我可以向你保证,任何从函数中“泄漏”的东西QLibrary::setFileNameAndVersion()都是故意留下的。X11/glibc/fontConfig 留下的内存位可能也不是错误。

它可以被视为不好的编码习惯或礼仪,但它也可以大大简化某些类型的任务。如今的操作系统为清理进程在终止(正常或强制)时留下的任何内存或资源提供了非常强大的保证,并且如果在应用程序的持续时间内很可能需要相关分配,包括关闭过程——以及 QT 的各种核心组件都符合条件——然后它可以在加载/初始化后立即让库设置一些内存分配,并允许这些内存分配无限期地持续存在。除其他外,这允许内存存在以供可能引用该内存的任何其他 C++ 析构函数使用。

由于这些分配只设置一次,并且从代码中的某一点开始,就不存在有意义的 内存泄漏的风险。它只是属于进程的内存,因此在操作系统关闭进程时会被清理。

结论:如果内存泄漏不在您的代码中,并且随着时间的推移它似乎没有变得明显更大(并且这些天很重要,想想兆字节),和/或显然源自首次初始化设置代码在您的应用程序中只调用一次,然后不用担心。这可能是故意的。

于 2012-12-28T18:22:08.780 回答
0

测试这一点的一种方法是在循环中运行代码,并改变迭代次数。如果 allocs 和 frees 之间的差异与迭代次数无关,那么您很可能是安全的。

于 2016-05-16T10:16:35.337 回答