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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QByteArray утечка памяти  (Прочитано 5619 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« : Август 23, 2011, 09:22 »

Есть такой вот незамысловатый пример

Код:
#include <QtCore/QCoreApplication>

#include <QFile>
#include <QByteArray>
#include <QThread>
#include <QByteArray>
#include <QDebug>

class Thread : public QThread
{
    Q_OBJECT

    public :
            Thread(QObject *parent = 0):QThread(parent){}

        void run()
        {
            while (true)
            {
                check_queue();
                usleep(50);
            }
        }

        void addQueue(QByteArray * data)
        {
            listByte << data;
        }

    private :
        QList<QByteArray *> listByte;

        void check_queue()
        {
            if (!listByte.isEmpty())
            {
                if (listByte[0] != NULL)
                {
                    delete listByte[0];
                    listByte[0] = NULL;
                }
            }
        }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int indexFile = 1;

    QString filePath = "D:/MyDocument/Picture/camera/%1.jpg";

    Thread *thread = new Thread();
    thread->start();

    while (true)
    {
        qDebug() << "open file" << filePath.arg(indexFile);
        QFile file(filePath.arg(indexFile));
        file.open(QIODevice::ReadOnly);
        QByteArray *data = new QByteArray(file.readAll());
        thread->addQueue(data);
        file.close();

        ++indexFile;
        if (indexFile == 10)
            indexFile = 1;
    }

    return 0;
}

#include "main.moc"


насколько могу понять, здесь память утекает в QByteArray , но не могу понять почему. Ведь вроде как передается он по указателю ,а потом удаляется. Или я что то упускаю ?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Август 23, 2011, 09:25 »

delete listByte.takeFirst ();
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #2 : Август 23, 2011, 09:46 »

да, спасибо, так гораздо лучше Улыбающийся
Записан
SimpleSunny
Гость
« Ответ #3 : Август 23, 2011, 10:46 »

1.Также возможна ошибка с гонкой за listByte, если функция "просто вызывается".
Код
C++ (Qt)
Thread t;
...
t.addQueue(b);

В данном случае надо использовать или слот, соединив его с соответствующим сигналом,  или invokeMethod(Qt::QueuedConnection), или Mutex.

2. Может вместо if (!listByte.isEmpty()) подразумевалось while (!listByte.isEmpty()).
« Последнее редактирование: Август 23, 2011, 10:49 от SimpleSunny » Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #4 : Август 23, 2011, 11:07 »

1. У меня в оригинальной софтине, слот, здесь просто пример на скорую руку, так сказать  Улыбающийся
2. Да while, торопился Улыбающийся

Что больше всего мне было непонятно в оригинальной софтине я для удаления из списка объекта использовал removeAt(0) ,ну и перед этим delete конечно, но память почему то утекала, не понимаю почему, но с takeFirst() работает хорошо.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Август 23, 2011, 12:35 »

Синхронизацией пока и не пахло (наверное отложил на потом)
Записан
SimpleSunny
Гость
« Ответ #6 : Август 23, 2011, 17:45 »

Кстати, так как, сам обьект Thread живет не в своем собственном потоке, а там где он создан, то и слоты будут выполняться в контексте потока в котором он создан. Чтобы слоты выполнялись в потоке Thread, надо его вручную туда переместить.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #7 : Август 23, 2011, 18:50 »

стало быть в ф-ции run() выполнить moveThread(this) ? я правильно понимаю ? про слоты не знал, спасибо Улыбающийся
Записан
SimpleSunny
Гость
« Ответ #8 : Август 23, 2011, 19:27 »

В конструкторе
Thread(QObject *parent = 0):QThread(parent){ moveToThread(this); }
Но насколько помню, если задан parent, то конструкция не отработает как ожидается.
На форуме было обсуждение использовать\не_использовать moveToThread(this);
UPD. http://www.prog.org.ru/topic_17090_0.html
« Последнее редактирование: Август 23, 2011, 20:02 от SimpleSunny » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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