Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: vbi от Март 07, 2012, 13:09



Название: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 13:09
У меня многопоточное приложение. Во время работы создается поток, работает и удаляется. на его место создаются другие потоки. Вот фрагмент кода конструктора:

Код:
  
MyThread::MyThread(QString textPar, QObject *parent):
    QThread(parent)
{
...

Пишу под Linux. Решил проверить Valgrind"ом на утечки памяти. Валгринд выводит утечку памяти для каждого существующего потока, в строчке № 11, которая в приведенном выше коде это:
Код:
    QThread(parent)
.

Вот вывод валгринда:
Цитировать
2,996 (240 direct, 2,756 indirect) bytes in 4 blocks are definitely lost in loss record 10,481 of 10,778
  в MyThread::MyThread(QString, QObject*) в MyThread.cpp:11
  1: operator new(unsigned int) в /build/buildd/valgrind-3.6.1/coregrind/m_replacemalloc/vg_replace_malloc.c:255
  2: /home/valery/QtSDK/Desktop/Qt/4.8.0/gcc/lib/libQtCore.so.4.8.0
  3: QThread::QThread(QObject*) в /home/valery/QtSDK/Desktop/Qt/4.8.0/gcc/lib/libQtCore.so.4.8.0
  4: MyThread::MyThread(QString, QObject*) в MyThread.cpp:11

Не могу понять, что я не так сделал. Почему утечка именно в этом месте? Или это глюк QT?


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: GreatSnake от Март 07, 2012, 15:26
Насчёт утечки ничего не скажу, но передавать копию строки вместо константной ссылки - моветон.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 15:46
Вы имеете ввиду
Цитировать
const QString textPar
?


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: mutineer от Март 07, 2012, 15:49
Насчёт утечки ничего не скажу, но передавать копию строки вместо константной ссылки - моветон.

Ну оно какбе SharedData, так что оверхед не сильно большой

а по теме, пардон за глупый вопрос, удаление тредов корректное?


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: GreatSnake от Март 07, 2012, 15:49
Вы имеете ввиду
Цитировать
const QString textPar
?
Нет, это
Цитировать
const QString& textPar


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: LisandreL от Март 07, 2012, 15:56
С утечкой очень сомнительно, но на всякий случай попробуйте с другой версией Qt и покажите побольше кода.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 16:20
В методе Run() прописано удаление:
Цитировать
connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
может он не работает. но финишед работает точно, так как у меня на finished() еще счетчик подвешен, по которому я вижу сколько потоков в данный момент.

Подскажите хотябы в какую сторону копать: Проблема именно в этой строке
Цитировать
    QThread(parent)
или всетаке в моем класе, наследуемом от QThread? типа не всю память освобождает.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 16:22
В Qt 4.7.4 - то же самое


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: GreatSnake от Март 07, 2012, 16:30
Вставь отладочную печать в деструктор MyThread.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: Igors от Март 07, 2012, 16:51
В методе Run() прописано удаление:
Цитировать
connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
может он не работает. но финишед работает точно, так как у меня на finished() еще счетчик подвешен, по которому я вижу сколько потоков в данный момент.
deleteLater не имеет эффекта (будет утеряно) если QEventLoop нитки не запущен или уже завершен. Проще мочить ее в том же месте где уменьшается счетчик


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 17:02
Вставь отладочную печать в деструктор MyThread.
Гениальная мысль! Вставил выводится. Но я вставил еще и в конструктор. Получилась странная картина:


Попытки |Кол. вызовов констр. | Кол. вызовов  дестр.
1844866
2194216

 Получается что в обеих случаях деструктор вызывался на 22 раза больше чем конструктор. Почему?


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: GreatSnake от Март 07, 2012, 17:11
Получается что в обеих случаях деструктор вызывался на 22 раза больше чем конструктор. Почему?
Что-то намудрил со счётчиками.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 17:16
Да нет сдесь счетчиков. Я в конструктор вставил
Цитировать
qDebug() << "begin      ";
а в деструктор
Цитировать
qDebug() << "      end";
потом подсчитал сколько выводится бегинов а сколько ендов. В 3 попытке ендов на 11 было больше, не на 22.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 07, 2012, 17:28
Разве сингал finished() где-то несколько раз отправляется


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: mutineer от Март 07, 2012, 18:05
Разве сингал finished() где-то несколько раз отправляется

это не влияет. сколько бы deleteLater() ты не послал, удалится объект все равно только один раз


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: Igors от Март 07, 2012, 18:15
потом подсчитал сколько выводится бегинов а сколько ендов. В 3 попытке ендов на 11 было больше, не на 22.
Добавьте член класса - счетчик удалений и попечатайте его. А проще снести deleteLater и удалять явно и в одном месте


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 13, 2012, 16:54
Нет, всетаки деструктор вызывается столько раз сколько и конструктор, все правильно. То ли я что-то подправил, толи неправильно считал.
Но на счет утечек памяти проблема остается актуальной.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: sudo от Март 13, 2012, 19:09
Деструктор виртуальный?


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: BRE от Март 13, 2012, 19:11
Деструктор виртуальный?
Ну если речь идет о QThread, он наследник QObject, у которого деструктор виртуальный, то какой ответ?


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: sudo от Март 14, 2012, 10:38
Деструктор виртуальный?
Ну если речь идет о QThread, он наследник QObject, у которого деструктор виртуальный, то какой ответ?

Правильный :D Заблокируйте мне форум после 8 вечера :D


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 16, 2012, 11:49
И виртуальный пробовал и невиртуальный.

Решить проблему помог отказ от наследования класса QThread. Респект автору этой темы http://www.prog.org.ru/topic_17090_0.html (http://www.prog.org.ru/topic_17090_0.html)
Утечки пропали!


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: Bepec от Март 16, 2012, 18:57
Печально. Особенно когда проблему решают методом - а я что нить уберу и вдруг оно заработает :) Как и вы в данном случае.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: vbi от Март 16, 2012, 22:42
Ну извените, я месяц над даной проблемой бился и все без результатно, тут тоже ничего не подсказали. Хорошо удалось хотябы "решить" проблему, пусть и не разобраться. Но тема открыта и можно продолжать обсуждение.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: V1KT0P от Март 17, 2012, 00:42
Ну извените, я месяц над даной проблемой бился и все без результатно, тут тоже ничего не подсказали. Хорошо удалось хотябы "решить" проблему, пусть и не разобраться. Но тема открыта и можно продолжать обсуждение.
Без минимального кода с утечкой как-то неинтересно.


Название: Re: Утечка памяти в конструкторе QThread
Отправлено: Bepec от Март 19, 2012, 09:05
Телепаты в отпуске, а корону короля телепатов у меня ещё в прошлом году отняли. За нецелесообразное использование...