crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Утечка памяти QTreeWidget. Может баг QT ?
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
dreamcode Дата 9.8.2010, 13:32
 
Цитата(Авварон @ 9.8.2010, 8:59) *
Удалив строку, ты освободищь память в куче и создав такую же строку еще раз, память у ОС запрашиваться не будет (в диспетчере будет те же 500мб)


Для теста напиши вставку в лист 1000 строк (посмотри на память в диспетчере) она возрастет

потом очисть лист (смотрим опять в диспетчер) . О ЧУДО память уменьшилась .

Как тогда такое объяснить то ???
Алексей1153 Дата 9.8.2010, 13:30
  dreamcode, щас времени повозиться нет (на работе), но, может сам сможешь (если чё - вечером сам попробую) - произведи класс от QTreeWidgetItem

там в конструкторе и деструкторе выводи в консоль соответствующие сообщения. Если деструкторов вызвалось столько же, сколько конструкторов - то всё ок, а значит, ошибка в Qt.

много элементов тут не нужно создавать
dreamcode Дата 9.8.2010, 13:25
 
Цитата(Авварон @ 9.8.2010, 8:59) *
блин, еще раз - диспетчер показывает ОБЩУЮ память приложения, когда-либо выделенную осью аппликухе. Удалив айтемы, память операционке ты не вернешь (да и не нужно это). В куче будет свободная память, которая может быть использована как повторно в тривьюхе, так и в других местах. Пример - создав строку размером 500 метров ты отожрешь 500 метров ОП и диспетчер этр покажет. Удалив строку, ты освободищь память в куче и создав такую же строку еще раз, память у ОС запрашиваться не будет (в диспетчере будет те же 500мб)



А вот и ни фига... Когда выделил память один рас (500 метров ушло) потом очистил и опять выделяешь (и опять 500 метров ушло) в суме уже один гиг.... Но так и всю оперативу можно израсходовать !!!!


Что же тогда делать ???
Алексей1153 Дата 9.8.2010, 12:36
 
Цитата(igor_bogomolov @ 9.8.2010, 15:20) *
Красную надпись объяснить легко
"QList<T>::operator[]", "index out of range"

Ну вот нет, не совсем всё так просто... Дело в том, что размер QList в моменты удаления элементов дерева не меняется - он вообще ничего не знает об этом. Индексы все корректные, но природу надписи что-то я не понял, когда сейчас попристальнее присмотрелся - даже ещё когда элементы не удалены из дерева, надпись тоже появляется ))
(хотя, до удаления по указателю сидят, и это видно через вьюер переменных, корректные данные, а после удаления - not accessible)


Цитата(igor_bogomolov @ 9.8.2010, 15:20) *
Тогда уж так

ну а тут разницы никакой, дело привычки. Я как-то while вобще не использую :)
igor_bogomolov Дата 9.8.2010, 12:20
 
Цитата(Алексей1153)
у меня в креаторе тоже не выпало, но надпись в консоли красным цветом появилась всё же
Красную надпись объяснить легко
inline const T &QList<T>::operator[](int i) const
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::operator[]", "index out of range");
return reinterpret_cast<Node *>(p.at(i))->t(); }

К сожалению (а может и к счастью) ошибка сегментации, так же как и деление на ноль, не являются исключениями с++ и через try/catch ты их не отловишь.

Цитата(Алексей1153)
    for(;ui->treeWidget->topLevelItemCount();)
    {
        delete ui->treeWidget->topLevelItem(0);
    }
Тогда уж так
while (ui->treeWidget->topLevelItemCount())
    delete ui->treeWidget->topLevelItem(0);
Алексей1153 Дата 9.8.2010, 12:00
  Авварон, у меня в креаторе тоже не выпало, но надпись в консоли красным цветом появилась всё же
Авварон Дата 9.8.2010, 11:27
 
Цитата(Алексей1153 @ 9.8.2010, 10:21) *
Можно потестировать вручную :)

//некая глобальная переменная
QList<QTreeWidgetItem*> m_ControlList;


...
{
   ...
   QTreeWidgetItem* item = new QTreeWidgetItem(0);
   m_ControlList.append(item);
}


Затем, после удаления, зайти отладчиком и попробовать доступ к каждому из элементов
    for(;ui->treeWidget->topLevelItemCount();)
    {
        delete ui->treeWidget->topLevelItem(0);
    }
    
    for(int i=0;i<m_ControlList.size();i++)
    {
        try
        {
            m_ControlList[i]->parent();
        }
        catch(...)
        {
            //память недоступна
            int iii=1;
        }
    }


в консоли приложения при попытке обращения пишут
(Internal error: pc 0x201 in read in psymtab, but not in symtab.)
(хотя исключение не летит, хм, прикольно. В студии вылетает с треском :D )


в с++ SIGSEGV не выкидывает искючений
Алексей1153 Дата 9.8.2010, 9:21
  Можно потестировать вручную :)

//некая глобальная переменная
QList<QTreeWidgetItem*> m_ControlList;


...
{
   ...
   QTreeWidgetItem* item = new QTreeWidgetItem(0);
   m_ControlList.append(item);
}


Затем, после удаления, зайти отладчиком и попробовать доступ к каждому из элементов
    for(;ui->treeWidget->topLevelItemCount();)
    {
        delete ui->treeWidget->topLevelItem(0);
    }
    
    for(int i=0;i<m_ControlList.size();i++)
    {
        try
        {
            m_ControlList[i]->parent();
        }
        catch(...)
        {
            //память недоступна
            int iii=1;
        }
    }


в консоли приложения при попытке обращения пишут
(Internal error: pc 0x201 in read in psymtab, but not in symtab.)
(хотя исключение не летит, хм, прикольно. В студии вылетает с треском :D )
Авварон Дата 9.8.2010, 8:59
 
Цитата(dreamcode @ 9.8.2010, 9:07) *
Аргументируй тогда куда память девается !!!!

блин, еще раз - диспетчер показывает ОБЩУЮ память приложения, когда-либо выделенную осью аппликухе. Удалив айтемы, память операционке ты не вернешь (да и не нужно это). В куче будет свободная память, которая может быть использована как повторно в тривьюхе, так и в других местах. Пример - создав строку размером 500 метров ты отожрешь 500 метров ОП и диспетчер этр покажет. Удалив строку, ты освободищь память в куче и создав такую же строку еще раз, память у ОС запрашиваться не будет (в диспетчере будет те же 500мб)
Алексей1153 Дата 9.8.2010, 8:47
  а вот такой код удаления, наверное, лучше
    for(;ui->treeWidget->topLevelItemCount();)
    {
        delete ui->treeWidget->topLevelItem(0);
    }


Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 29.3.2024, 14:54