【发布时间】:2012-08-14 00:18:15
【问题描述】:
我对以下代码有疑问:
#include <QtGui/QImage>
int main(int argc, char* argv[]) {
QImage qimage(100, 100, QImage::Format_ARGB32);
qimage.fill(Qt::white);
qimage.save("test.png", "PNG", 70);
return 0;
}
编译如下:
gcc -I/usr/include/qt4 test.cpp -lQtGui
代码生成正确的图像。但是,当我对它进行 valgrind 时:
valgrind --leak-check=full ./a.out
它会产生一系列丢失的块,如下所示:
==5974== 158 (56 direct, 102 indirect) bytes in 1 blocks are definitely lost in loss record 54 of 79
==5974== at 0x402B9B4: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5974== by 0x4E4E427: QLibraryPrivate::findOrCreate(QString const&, QString const&) (qlibrary.cpp:437)
==5974== by 0x4E4E721: QLibrary::setFileNameAndVersion(QString const&, QString const&) (qlibrary.cpp:1110)
==5974== by 0x56290DF: ???
或者这个:
==5974== 396 (56 direct, 340 indirect) bytes in 1 blocks are definitely lost in loss record 61 of 79
==5974== at 0x402B9B4: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5974== by 0x4E4E427: QLibraryPrivate::findOrCreate(QString const&, QString const&) (qlibrary.cpp:437)
==5974== by 0x4E44FB6: QFactoryLoader::updateDir(QString const&, QSettings&) (qfactoryloader.cpp:145)
==5974== by 0x56F9E67: ???
我给你完整的日志,你可以在家里执行同样的操作:)
我试图理解,它们似乎位于我在 QImageWriter 的源代码中找到的以下几行:
QFactoryLoader *l = loader();
QStringList keys = l->keys();
在我看来,当您第一次尝试生成 PNG 图像时,它会构建一些内容,每次构建 PNG 图像时都会重复使用这些内容,并且永远不会释放内存。
QFactoryLoader 的析构函数似乎知道如何清理东西,我很想亲自做一个delete l; 但没有办法调用它,因为 QFactoryLoader 是 Qt 实现的私有。
有人可能会说这不是真正的内存泄漏,因为每种图像格式只有一个键,但恕我直言,做事的干净方法是能够在退出前清除所有内容。
所以我的问题是:有没有办法做到这一点?
【问题讨论】:
-
你不应该为这类问题烦恼,因为 Qt 有系统可以释放所有未使用的内存。您正在寻找不存在的问题。 Qt 将在销毁 qimage 对象时释放此内存。不知道为什么 valgrind 没有看到。
-
如果你在任何更大的基于 Qt 的项目上运行 Valgrind,它将在 Qt 实现中发现数百个可能的内存泄漏。我不知道所有这些是否都是真正的内存泄漏,或者 valgrind 是否只是因为 Qt 中大量使用指针而感到困惑。但是,如前所述,我不会为此烦恼。