问题
I have an issue with the following code:
#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;
}
to be compiled as followed:
gcc -I/usr/include/qt4 test.cpp -lQtGui
The code generates a proper image. However, when I valgrind it:
valgrind --leak-check=full ./a.out
it yields a series of lost blocks, like the following one:
==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: ???
or this one :
==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: ???
I spare you the full log, you can just execute the same at home :)
I tried to understand and they seems to lie in the following lines I found in the source code for QImageWriter:
QFactoryLoader *l = loader();
QStringList keys = l->keys();
It seems to me that when you first try to generate a PNG image, it builds something that will be reused each time you will build a PNG image and that memory is never freed.
The destructor for QFactoryLoader seems to know how to clean things, and I would love to personally do a delete l;
but there is no way to call it since QFactoryLoader is private to the implementation of Qt.
One could argue that this is not a real memory leak since there would be only one key per image format, but imho, the clean way to do things would be to be able to clear everything before quitting.
So my question: is there any way to do that?
回答1:
Qt's image I/O functionality is based around plugins. When you request a QImage
to a load a png file the PNG library is loaded as a QObject
once, it is not unloaded until the program exits - this is what Valgrind sees as a memory leak.
回答2:
Why aren't you using the QCoreApplication. Only then the QObject GC will be in action. Only then proper clean up will work. Qt is internally built around too many pointers which are managed by the main event loop with out which it is totally messy and destructive.
来源:https://stackoverflow.com/questions/11937218/qimage-and-valgrind-memory-leak