Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [qt] выделение памяти и ее освобождение


Автор: brag 16.5.2009, 12:07
добрый день!
я в C++ не силен,тем более в QT. моя стихия - низкоуровневое програмирование smile
подскажите,плиз такую вещь:
если есть QTableWidget, в него надо напихать, скажем 1000записей.
как я понял,создается новый экземпляр обьекта QTableWidgetItem
item=new QTableWidgetItem(tr("aaa"));
и затем пихается в этот QTableWidget
ui.tableWidget->setItem(row,col,item);

а как быть с освобождением памяти? если,мне, скажем, нужно записать новые данные в таблицу?
я делал
tableWidget->clearContents();
tableWidget->setRowCount(0);
но по стату видно,что память, выделенная приложению растет.
те, получается,нужно так же в цикле доставать адреса всех итемов и освобождать?
или есть какие-то более красивые решения? даже в winapi простой listview можно освободить одним сообщением

за ренее,спасибо!

Автор: Remiznik 16.5.2009, 13:07
а попробовать использовать 

void QTableWidget::removeCellWidget ( int row, int column )

Removes the widget set on the cell indicated by row and column.

Автор: brag 16.5.2009, 13:34
всеравно память растет :(
причем именно растет, а не выделяются ранее неиспользованные, но выделенные стртаницы.
я думал, тут все намного проще, а получается сложнее..мне на своем низком уровне нужно следить за выделением/освобождением, а тут надо ещ больше следить smile

Добавлено через 7 минут и 39 секунд
парится с очисткой не надо, достаточно 
tableWidget->setRowCount(0);
и оно прочистит. только сами обьекты остануться выделенными и будут накоплять память.
провервл.
с таблицей с данными делал
tableWidget->setRowCount(0);
tableWidget->setRowCount(2);
2 строки появились, но пустые.

прийдется писать метод для бегания по таблице и освобождения памяти

Автор: brag 16.5.2009, 13:55
сварганил что-то подобное
Код

void MainFrm::freeTableWidget(QTableWidget *t){
    int i,j,r,c;
    c=t->columnCount();
    r=t->rowCount();
    for(i=0;i<r;++i){
        for(j=0;j<c;++j){
            delete t->item(i,j);
        }
    }
    t->setRowCount(0);
}

но память всеравно растет smile 

Автор: Remiznik 16.5.2009, 13:57
я не уверен а попробуй создавать QTableWidgetItem не динамически , а передовать через ссылку !
незнаю что получиться и реаьно ли вобше это !

Добавлено через 4 минуты
Цитата(brag @ 16.5.2009,  13:55)
сварганил что-то подобное
Код

void MainFrm::freeTableWidget(QTableWidget *t){
    int i,j,r,c;
    c=t->columnCount();
    r=t->rowCount();
    for(i=0;i<r;++i){
        for(j=0;j<c;++j){
            delete t->item(i,j);
        }
    }
    t->setRowCount(0);
}

но память всеравно растет smile

для удаления нужно брать итем !

QTableWidgetItem * QTableWidget::takeItem ( int row, int column )

Removes the item at row and column from the table without deleting it.

Автор: SABROG 16.5.2009, 15:16
Цитата(brag @  16.5.2009,  12:07 Найти цитируемый пост)
я делал
tableWidget->clearContents();


Эта функция очищает только содержимое ячеек, но никак не удаляет сами элементы. Используй

http://doc.qtsoftware.com/latest/qtablewidget.html#clear

Если в чем-то не уверен - создай тестовый код:

Код

#include <QtGui/QApplication>
#include <QtGui/QTableWidget>
#include <QtGui/QTableWidgetItem>

enum{RowCount=100000, ColumnCount=10};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QTableWidget *tableWidget = new QTableWidget;
    tableWidget->setRowCount(RowCount);
    tableWidget->setColumnCount(ColumnCount);
    for (int i=0; i < RowCount; ++i) {
        for (int j=0; j < ColumnCount; ++j) {
            QTableWidgetItem *item = new QTableWidgetItem(QString("%0:%1")
                    .arg(i).arg(j));
            tableWidget->setItem(i, j, item);
        }
    }
    tableWidget->clear();
    tableWidget->show();
    return app.exec();
}



В простейшем случае в Task Manager'e будет видно максимальное количество используемой памяти и текущее количество. Например у меня 100000*10 элементов занимает в памяти 150Мб, после clear() - 11Мб. Но я не доверяю Task Manager'у, поэтому использую детекторы утечек памяти такие как Valgrind (для Linux) и Rational Purify (для Windows). И вот что последний говорит:

Цитата

[I] Summary of all memory leaks... {138 bytes, 3 blocks}
[I] MPK: Potential memory leak of 106 bytes from 1 block allocated in lock [MSVCRT.DLL]
        Offset 0x00000009 referenced by 0x028c4e50, a location in a malloc'd block
        Offset 0x00000009 referenced by 0x028c4d88, a location in a malloc'd block
        Distribution of potentially leaked blocks
               106 bytes from 1 block of 106 bytes (0x028c4d88)
        Allocation location
            malloc         [C:\WINDOWS\system32\MSVCRT.DLL]
            lock           [C:\WINDOWS\system32\MSVCRT.DLL]
[I] MPK: Potential memory leak of 32 bytes from 2 blocks allocated in ZN8QMapData11node_createEPPNS_4NodeEi [QTCORE4.DLL]
        Offset 0x00000008 referenced by 0x04399490, a location in a malloc'd block
        Offset 0x00000008 referenced by 0x043a88d4, a location in a malloc'd block
        Distribution of potentially leaked blocks
                32 bytes from 2 blocks of 16 bytes (first block: 0x04399500)
        Allocation location
            malloc         [C:\WINDOWS\system32\MSVCRT.DLL]
            ZN8QMapData11node_createEPPNS_4NodeEi [D:\WORK\TWITEMMEMLEAK\RELEASE\QTCORE4.DLL]


Грубо говоря - утечек нет.

Автор: brag 16.5.2009, 16:05
так я же передаю через ссылку. или вы предлагаете статически наклепать? статически не идет,тк коли-ество итемов разное.
QTableWidgetItem * QTableWidget::takeItem ( int row, int column )
Removes the item at row and column from the table without deleting it.
написано же,что без удаления. попробую конечно

Добавлено через 1 минуту и 25 секунд
SABROG, спасибо!
иду пробовать smile

Автор: SABROG 16.5.2009, 16:07
Цитата(brag @  16.5.2009,  12:07 Найти цитируемый пост)
item=new QTableWidgetItem(tr("aaa"));
и затем пихается в этот QTableWidget
ui.tableWidget->setItem(row,col,item);


Это в каком месте тут у тебя ссылка?

Автор: brag 16.5.2009, 16:15
утечки есть, но не большие... спасибо
у меня qt4. freebsd

Добавлено через 1 минуту и 8 секунд
Цитата(SABROG @  16.5.2009,  16:07 Найти цитируемый пост)
Это в каком месте тут у тебя ссылка?

QTableWidgetItem *item;
item=new QTableWidgetItem(tr("aaa"));
чем не ссылка?

Автор: SABROG 16.5.2009, 16:22
Цитата(brag @  16.5.2009,  16:15 Найти цитируемый пост)
QTableWidgetItem *item;
item=new QTableWidgetItem(tr("aaa"));
чем не ссылка? 


Как-то обсуждали тему интересную http://forum.vingrad.ru/index.php?showtopic=240676&view=findpost&p=1731142

Автор: brag 17.5.2009, 10:25
спасибо,почитал! о этой штуке я и не знал. но пока не важно,хватит и привычных указателей, тк буду путаться smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)