Russian Qt Forum
Ноябрь 23, 2024, 06:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Утечка памяти в конструкторе QThread  (Прочитано 12838 раз)
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?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Март 07, 2012, 15:26 »

Насчёт утечки ничего не скажу, но передавать копию строки вместо константной ссылки - моветон.
Записан

Qt 5.11/4.8.7 (X11/Win)
vbi
Гость
« Ответ #2 : Март 07, 2012, 15:46 »

Вы имеете ввиду
Цитировать
const QString textPar
?
Записан
mutineer
Гость
« Ответ #3 : Март 07, 2012, 15:49 »

Насчёт утечки ничего не скажу, но передавать копию строки вместо константной ссылки - моветон.

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

а по теме, пардон за глупый вопрос, удаление тредов корректное?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Март 07, 2012, 15:49 »

Вы имеете ввиду
Цитировать
const QString textPar
?
Нет, это
Цитировать
const QString& textPar
Записан

Qt 5.11/4.8.7 (X11/Win)
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #5 : Март 07, 2012, 15:56 »

С утечкой очень сомнительно, но на всякий случай попробуйте с другой версией Qt и покажите побольше кода.
Записан
vbi
Гость
« Ответ #6 : Март 07, 2012, 16:20 »

В методе Run() прописано удаление:
Цитировать
connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
может он не работает. но финишед работает точно, так как у меня на finished() еще счетчик подвешен, по которому я вижу сколько потоков в данный момент.

Подскажите хотябы в какую сторону копать: Проблема именно в этой строке
Цитировать
    QThread(parent)
или всетаке в моем класе, наследуемом от QThread? типа не всю память освобождает.
Записан
vbi
Гость
« Ответ #7 : Март 07, 2012, 16:22 »

В Qt 4.7.4 - то же самое
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Март 07, 2012, 16:30 »

Вставь отладочную печать в деструктор MyThread.
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Март 07, 2012, 16:51 »

В методе Run() прописано удаление:
Цитировать
connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
может он не работает. но финишед работает точно, так как у меня на finished() еще счетчик подвешен, по которому я вижу сколько потоков в данный момент.
deleteLater не имеет эффекта (будет утеряно) если QEventLoop нитки не запущен или уже завершен. Проще мочить ее в том же месте где уменьшается счетчик
Записан
vbi
Гость
« Ответ #10 : Март 07, 2012, 17:02 »

Вставь отладочную печать в деструктор MyThread.
Гениальная мысль! Вставил выводится. Но я вставил еще и в конструктор. Получилась странная картина:


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

 Получается что в обеих случаях деструктор вызывался на 22 раза больше чем конструктор. Почему?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Март 07, 2012, 17:11 »

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

Qt 5.11/4.8.7 (X11/Win)
vbi
Гость
« Ответ #12 : Март 07, 2012, 17:16 »

Да нет сдесь счетчиков. Я в конструктор вставил
Цитировать
qDebug() << "begin      ";
а в деструктор
Цитировать
qDebug() << "      end";
потом подсчитал сколько выводится бегинов а сколько ендов. В 3 попытке ендов на 11 было больше, не на 22.
Записан
vbi
Гость
« Ответ #13 : Март 07, 2012, 17:28 »

Разве сингал finished() где-то несколько раз отправляется
Записан
mutineer
Гость
« Ответ #14 : Март 07, 2012, 18:05 »

Разве сингал finished() где-то несколько раз отправляется

это не влияет. сколько бы deleteLater() ты не послал, удалится объект все равно только один раз
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.185 секунд. Запросов: 22.