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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QList . Как узнать, правильно ли удаляются указатели?  (Прочитано 11522 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Январь 20, 2009, 10:02 »



Доброго времени суток!

как проверить код на утечки памяти?

например я написал код в котором создаются некие объекты, указатели на которые я помещаю в QList

Код:
void Dialog::slNew()
{
    for (int i = 0; i<100000; ++i) {
        TestClass *tc = new TestClass; //создаю мои объекты
        tc->setValue(++cnt); //это просто для проверки объекта потом
        clist.append(tc); //в лист указатели на объекты вношу
    }
}


и очищаю лист как приведено в ассистенте:

Код:
void Dialog::slDel()
{
while (!clist.isEmpty())
delete clist.takeFirst();
}

пробовал смотреть в винде через диспетчер задач...
при запуске приложения выделяется к примеру 3 Мб.. жму - создать объекты - становиться к примеру 18 Мб...
жму очистить лист - становится 7Мб ...

т.е получается, что память все больше и больше "кушается" Непонимающий т.е есть утечка?
Записан

ArchLinux x86_64 / Win10 64 bit
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Январь 20, 2009, 10:08 »

2 kuzulis, для чистоты проверь в несколько итераций, если возвращается к одному и тому же значению, то скорее всего утечки нет.
Записан

Юра.
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Январь 20, 2009, 10:41 »

Цитировать
2 kuzulis, для чистоты проверь в несколько итераций, если возвращается к одному и тому же значению, то скорее всего утечки нет.
не... потребление памяти растет ... я сделал i<1000000 .... и после удаления и последующего создания - память не высвобождается польностью, а накапливается... вот накопил до 60 Мб Улыбающийся

но ведь после delete нужно обнулить указатель... а как это в QList можно сделать? ведь после удаления из QList - уже доступ никак к указателю через QList не получить (т.к он уже удален из QList)  В замешательстве
Записан

ArchLinux x86_64 / Win10 64 bit
Winstrol
Гость
« Ответ #3 : Январь 20, 2009, 10:51 »

но ведь после delete нужно обнулить указатель...
Обнулять указатели после delete не нужно. В профилактических целях даже нельзя.
Что касается утечки, то полный код код, локализованный в одной фунции посмотреть бы.
Записан
Rcus
Гость
« Ответ #4 : Январь 20, 2009, 10:53 »

Код
C++ (Qt)
void MainWindow::on_pushButton_clicked()
{
   for (int i = 0; i < 1000000; ++i)
       list.append(new QString("Test"));
   while (!list.isEmpty())
       delete list.takeFirst();
}

У меня в несколько модифицированном тесте объем потребляемой памяти стабилизировался после первой итерации, ищите дальше.
Записан
spirit
Гость
« Ответ #5 : Январь 20, 2009, 10:57 »

а dtor'ы TestClass и всех ваших классов вызываются и отрабатываются верно(поставте бряку или qDebug, что бы убедиться)?
ЗЫ. можно также для удаления юзать qDeleteAll.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #6 : Январь 20, 2009, 11:03 »

Цитировать
а dtor'ы TestClass и всех ваших классов вызываются и отрабатываются верно(поставте бряку или qDebug, что бы убедиться)?

если можно, то поподробнее пжлста ! где что ставить? (я ж новичек ! Улыбающийся )

вот реализация TestClass к примеру:

*.h
Код:
#ifndef MYCLASS_H
#define MYCLASS_H

class TestClass
{
public:
TestClass();
int getValue();
void setValue(int value);
private:
int testvalue;
};

#endif // MYCLASS_H

*.cpp
Код:
#include "myclass.h"

TestClass::TestClass()
{
testvalue = 0;
}

int TestClass::getValue()
{
return testvalue;
}

void TestClass::setValue(int value)
{
testvalue = value;
}
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Январь 20, 2009, 11:11 »

Цитировать
У меня в несколько модифицированном тесте объем потребляемой памяти стабилизировался после первой итерации, ищите дальше.

у меня если жмакаю "создать 10000 объектов" а потом жмакаю "очистить лист" - то тоже вроде устаканивается (хотя по 1-10 байт набирает потихоньку все-равно)

а вот если жмакаю несколько раз "создать 10000 объектов" - а потом "очистить лист" - то память накапливается!
Записан

ArchLinux x86_64 / Win10 64 bit
spirit
Гость
« Ответ #8 : Январь 20, 2009, 11:14 »

в класс TestClass добавте деструктор и там уже qDebug.
Код
C++ (Qt)
#include <QDebug>
....
TestClass::~TestClass()
{
    ....
    qDebug() << "TestClass::dtor called";
    ....
}
 
но вроде в коде все нормально.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #9 : Январь 20, 2009, 11:23 »

2 spirit

я сделал как посоветовали:
1. в консоли мильон раз (i<1000000) отобразилось сообщение:  TestClass::dtor called
2. пока оно выводилось - память потребляемая увеличивалась + приложение подвисло
3. после того как выводится сообщения перестали - память стабилизировалась + приложение отвисло
Записан

ArchLinux x86_64 / Win10 64 bit
Winstrol
Гость
« Ответ #10 : Январь 20, 2009, 11:53 »

На вид все вроде правильно.
Но:
-память очень желательно отдавать в обратном порядке тому, в котором она выделялась, если нет веских причин не делать этого. Это снизит фрагментацию кучи.
-выделять стандартным аллокатором кучу маленьких объектов - зло. Надо пользоваться каким либо small object allocator / pool и.т.п.
« Последнее редактирование: Январь 20, 2009, 11:54 от Winstrol » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #11 : Январь 20, 2009, 12:41 »

2 Winstrol ,

а где взять :
Цитировать
Надо пользоваться каким либо small object allocator / pool и.т.п.
Непонимающий

это спец. библиотека нужна с этими функциями?
Записан

ArchLinux x86_64 / Win10 64 bit
Winstrol
Гость
« Ответ #12 : Январь 20, 2009, 13:17 »

2 Winstrol ,

а где взять :
Цитировать
Надо пользоваться каким либо small object allocator / pool и.т.п.
Непонимающий

это спец. библиотека нужна с этими функциями?

Можно и самому написать - много где описано. Случай-то классический. Можно Boost скачать. Тогда примерно так будет выглядеть

Код
C++ (Qt)
boost::object_pool<TestClass> testClassAlloc;
....
void Dialog::slNew()
{
   for (int i = 0; i<100000; ++i) {
       //TestClass *tc = new TestClass; //создаю мои объекты
       TestClass *tc = testClassAlloc.construct(параметры конструктора);
       tc->setValue(++cnt); //это просто для проверки объекта потом
       clist.append(tc); //в лист указатели на объекты вношу
   }
}
void Dialog::slDel()
{
while (!clist.isEmpty())
          {
                     //delete clist.takeFirst();
                     TestClass* tc = clist.takeFirst();
                     testClassAlloc.destroy(tc);
          }
}
 

Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #13 : Январь 20, 2009, 13:27 »

2 Winstrol ,

спасибо, буду пробовать! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Winstrol
Гость
« Ответ #14 : Январь 20, 2009, 14:09 »

2 Winstrol ,

спасибо, буду пробовать! Улыбающийся
Прошу прощения. Так, как показал пробывать не надо.Улыбающийся И скачивать тоже не обязательно.
Код
C++ (Qt)
#include <memory>
std::allocator<TestClass> stdTestClassAlloc;
....
TestClass *tc = stdTestClassAlloc.allocate(1);
new (tc) TestClass(параметры коструктора); //создаю мои объекты
....
TestClass* tc = clist.takeFirst();
tc->~TestClass();
stdTestClassAlloc.deallocate(tc);
 
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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