Steve Lorimer
Steve Lorimer

Reputation: 28659

QT: how to properly clean up QSettings to prevent memory leak?

I have written the following small exemplar test case which simply writes a single key/value into a QSettings object (using Qt 5.5):

#include <QSettings>

int main()
{
    QSettings settings("/tmp/settings.ini", QSettings::IniFormat);

    std::string data = "world";
    QByteArray arr(data.c_str(), data.size());

    settings.setValue("hello", arr);
    return 0;
}

I have compiled it as follows:

$ g++ main.cpp -I${QTDIR}/include -I${QTDIR}/include/QtCore -fpic \
        -L${QTDIR}/lib -Wl,-R -Wl,"$QTDIR/lib" -lQt5Core -o test

Running it produces no stdout/stderr output, as expected

$ ./test

However, we can see that it worked as expected by looking at the "settings.ini" file it created:

$ cat /tmp/settings.ini 
[General]
hello=@ByteArray(world)

However, running it though valgrind reports a memory leak:

$ valgrind --quiet --leak-check=full ./test

==2148== 4 bytes in 1 blocks are definitely lost in loss record 1 of 4
==2148==    at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2148==    by 0x4EC4CA1: qrand() (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x5012CC3: ??? (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x4FE6291: QFile::open(QFlags<QIODevice::OpenModeFlag>) (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x5013350: QTemporaryFile::open(QFlags<QIODevice::OpenModeFlag>) (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x505CA7D: ??? (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x505DE8C: ??? (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x4FF5A3B: QLockFile::tryLock(int) (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x503DE80: ??? (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x503F0C8: QSettings::~QSettings() (in ${QTDIR}/lib/libQt5Core.so.5.5.0)
==2148==    by 0x400E72: main (in /home/steve/test)
==2148== 

As can be seen this is originating in the QSettings destructor.

QSettings::sync():

Note that calling settings.sync() makes no difference to the memory leak, all it does is move the leak to originate from within sync(), rather than the destructor.

This is to be expected, since the documentation states that sync() is called from the destructor.

Question:

How can I properly clean up to prevent this memory leak?

Upvotes: 2

Views: 1098

Answers (1)

It's a Qt bug, but you don't know yet if it's important or not. Check if you can make more memory leak. Do this whole thing 1000 times in a loop and if it leaks 1000 ints, you should definitely file a bug report. Otherwise it'll have low priority.

How can I properly clean up to prevent this memory leak?

You already are properly cleaning up. It's C++ and RAII classes, you shouldn't have to do anything. It's not C.

Upvotes: 2

Related Questions