LINUX.ORG.RU

Qt valgrind memleak

 memleak,


0

2

Всем доброго времени суток.

Есть проект на Qt. При запуске анализатора памяти valgrind из Qt Creator вываливается вот такая ошибка:

240,332 (156 direct, 240,176 indirect) bytes in 1 blocks are definitely lost in loss record 5,921 of 5,921
  в MyClock::MyClock(QLabel*) в myclock.cpp:4
  1: operator new(unsigned int) в /tmp/buildd/valgrind-3.6.0~svn11254+nmu1/coregrind/m_replacemalloc/vg_replace_malloc.c:255
  2: /home/ivan/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtGui.so.4.8.1
  3: QFontDatabase::load(QFontPrivate const*, int) в /home/ivan/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtGui.so.4.8.1
  4: QFontPrivate::engineForScript(int) const в /home/ivan/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtGui.so.4.8.1
  5: QFontInfo::pointSize() const в /home/ivan/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtGui.so.4.8.1
  6: MyClock::MyClock(QLabel*) в myclock.cpp:4
  7: MainWindow::initMainWgt() в mainwindow.cpp:25
  8: MainWindow::MainWindow(QWidget*, QFlags<Qt::WindowType>) в mainwindow.cpp:9
  9: main в main.cpp:16

Код класса MyClock, на который он ругается:

myclock.h

#ifndef MYCLOCK_H
#define MYCLOCK_H

#include <QDateTime>
#include <QLabel>
#include <QTimer>

class MyClock : public QLabel
{
private:
	QDateTime timestamp;

protected:
	virtual void timerEvent (QTimerEvent *);
	
public:
	explicit MyClock(QLabel *parent = 0);
	void showTime ();

};

#endif // MYCLOCK_H

myclock.cpp

#include "myclock.h"

MyClock::MyClock(QLabel *parent) : QLabel(parent) {
	setMaximumHeight (fontInfo ().pointSize ()*2); // вот здесь ругается
	showTime ();
	startTimer (1000);
}

void MyClock::showTime() {
	timestamp = QDateTime::currentDateTime ();
	setText (tr ("Текущее время: ") + timestamp.toString ("dd.MM.yyyy hh:mm:ss"));
}

void MyClock::timerEvent(QTimerEvent *) {
	showTime ();
}

Что-то я смотрю-смотрю, и не могу увидеть, где здесь утечка памяти =(

Буду признателен за помощь.

★★

Ответ на: комментарий от slackwarrior

Что-то мне подсказывает, что main не поможет =)

main.cpp

#include <QApplication>
#include <QTextCodec>
#include "mainwindow.h"

int main (int argc, char **argv) {
	QApplication app (argc, argv);
	QTranslator qtTranslator;
	qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
	app.installTranslator(&qtTranslator);
	
	QTextCodec::setCodecForCStrings (QTextCodec::codecForName ("utf-8"));
	QTextCodec::setCodecForTr (QTextCodec::codecForName ("utf-8"));
	QTextCodec::setCodecForLocale(QTextCodec::codecForName ("utf-8"));
	
	Qt::WindowFlags f = Qt::FramelessWindowHint;
	MainWindow wnd (0, f);
	wnd.show ();
	
	return app.exec ();
}

В конструкторе MainWindow падает здесь:

void MainWindow::initMainWgt() {
	pclock = new MyClock;
	...
	pMainLayout = new QVBoxLayout;
	pMainWgt = new QWidget;
	pMainLayout->addWidget (pclock, 0, Qt::AlignHCenter);
	...
	pMainWgt->setLayout (pMainLayout);
	setCentralWidget (pMainWgt);
        ...
}

Самостоятельно pсlock нигде не удаляю, но, насколько я понял, в этом и нет необходимости...

solovey ★★
() автор топика
Ответ на: комментарий от Belkrr

Да, если заменить fontInfo () на font (), то valgrind больше не ругается.

Спасибо за решение.

Однако интересно было бы узнать, в чем причина...

solovey ★★
() автор топика
Ответ на: комментарий от Gorthauer

Я думал, может кто сталкивался уже и знает, в чем причина...

solovey ★★
() автор топика
Ответ на: комментарий от solovey

pсlock не нужно удалять в том случае, если ты устанавливаешь для него родителя, то есть pclock = new MyClock (this).

А ругается скорее всего на какой-то глобальный статический буфер.

panter_dsd ★★★★
()
Последнее исправление: panter_dsd (всего исправлений: 1)
Ответ на: комментарий от solovey

http://www.qtcentre.org/threads/12439-Memory-leak-Detection-using-Valgrind http://stackoverflow.com/questions/9174326/suppression-files-for-qt-memory-le...

Если коротко, то нужно написать хеллоуворлд на кутэ, или что-то очень простое, где ты явно не мог ошибиться, и запустить валгринд с опцией get-suppressions=yes, это даст тебе файл с исключениями, который нужно будет потом использовать.

anonymous
()
Ответ на: комментарий от solovey

Причина в том, что fontInfo() создает новый объект, который надо бы удалять, а font использует уже существующий (и возвращает const &)

об этом есть в Assistant.

Belkrr
()
Ответ на: комментарий от panter_dsd

Да, я в курсе, но у Шлее также написано, что если родителя не задать, а потом добавить виджет в Layout, то этот Layout станет его родителем...

Вроде как-то так)

solovey ★★
() автор топика
Ответ на: комментарий от Belkrr

Спасибо, не знал. Про font и fontInfo читал, но, видимо, не внимательно...

solovey ★★
() автор топика
Ответ на: комментарий от solovey

Это да, но не всегда виджет нужно добавлять в лайот, так что, лучше приучить себя задавать парента изначально.

panter_dsd ★★★★
()
Ответ на: комментарий от solovey

На самом деле, если у тебя только эта ошибка, то скорее всего за тебя это уже сделано где-то.

anonymous
()
Ответ на: комментарий от panter_dsd

Согласен. Лишним все-равно не будет, а от глупых ошибок избавиться поможет...

solovey ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.