Usuwanie obiektów/klas. Jak zwolnić pamięć?

Odpowiedz Nowy wątek
2011-11-12 23:13
0

Witam.
Napisałem program składający się z dwóch klas MainWindow i BazaDanych. Pierwsza klasa ma 2 przyciski- jeden po nacisnieciu tworzy tą drugą i wypełnia(szczegóły w kodzie), natomiast drugi usuwa ją. Z tym, że no właśnie nie do końca usuwa, bo pamięci zwalnia się tyle co nic(w menedzeże pokazuje, że usuwa niecałe 2 mega z 50mb które ta klasa stworzyła) . I tu właśnie rodzi się pytanie jak usunąć dany obiekt/klasę ze wszystkim co ona stworzyła dynamicznie. W moim przypadku są to obiekty QStandardItems. Wiem, że QT ma coś takiego, że jak się usuwa rodzica to automatycznie usuwa jego "dzieci", ale chyba nie w tym przypadku.

Plik mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QHBoxLayout>
#include "bazadanych.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

    QHBoxLayout *layout;
    BazaDanych *baza;
    QPushButton *button1,*button2;

private slots:
    void createBase();
    void deleteBase();

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

plik mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    baza = 0;

    button1 = new QPushButton("stworz",this);
    button2 = new QPushButton("usun",this);

    layout = new QHBoxLayout;
    layout->addWidget(button1);
    layout->addWidget(button2);

    centralWidget()->setLayout(layout);

    connect(button1,SIGNAL(clicked()),this,SLOT(createBase()));
    connect(button2,SIGNAL(clicked()),this,SLOT(deleteBase()));

}

void MainWindow::createBase(){

    if(!baza)                                        //Stworzenie klasy baza
        baza = new BazaDanych();
            baza->CreateModel();                    //wypełnienie jej

}

void MainWindow::deleteBase(){
      if(baza)
        {
            delete baza;                  //Usuwanie  tej klasy nie usuwa jej wszystkich elementów?
                baza = 0;

        }

MainWindow::~MainWindow()
{
    delete ui;
}

plik bazadanych.h:


#ifndef BAZADANYCH_H
#define BAZADANYCH_H

#include <QObject>
#include <QStandardItem>
#include <QStandardItemModel>

class BazaDanych : public QObject
{
    Q_OBJECT

     QStandardItem *itemMark,*itemEngineSize,*itemPower,*itemMileage,*itemColour,*itemDamage,*itemYear;
     QStandardItemModel *model;
    int rowcount;

public:
    explicit BazaDanych(QObject *parent = 0);
    void CreateModel();
    ~BazaDanych();

signals:

public slots:

};

#endif // BAZADANYCH_H

plik bazadanych.cpp

#include "bazadanych.h"

BazaDanych::BazaDanych(QObject *parent) :
    QObject(parent)
{

    model = 0;

}

void BazaDanych::CreateModel(){

    if(!model){
        model = new QStandardItemModel;
            model->insertRow(1);
    }

  for (int i = 0; i < 50000; i++){
    rowcount = model->rowCount();
                                                                                 //wypełnianie modelu przez QStandardItem
    model->setItem(rowcount,0,itemMark = new QStandardItem("jakas wartosc"));
    model->setItem(rowcount,1,itemEngineSize = new QStandardItem("jakas wartosc"));
    model->setItem(rowcount,2,itemPower = new QStandardItem("jakas wartosc"));
    model->setItem(rowcount,3,itemYear = new QStandardItem("jakas wartosc"));
    model->setItem(rowcount,4,itemMileage = new QStandardItem("jakas wartosc"));
    model->setItem(rowcount,5,itemColour = new QStandardItem("jakas wartosc"));
    model->setItem(rowcount,6,itemDamage = new QStandardItem("jakas wartosc"));
}

}

BazaDanych::~BazaDanych(){

    model->clear();   //Czysci model, ale nie usuwa QStandardItem?
    delete model;     //Tak samo nie usuwa QStandardItem.

}

EDIT: Znalazłem taką informację:

QStandardItemModel::~QStandardItemModel ()
Destructs the model. The model destroys all its items.

Jak to użyć/zaimplementować?

edytowany 1x, ostatnio: Miszcz_, 2011-11-13 02:44

Pozostało 580 znaków

2011-11-13 06:08
0

Serio? :D Google -> C++ Destruktor.

No niech bedzie. Az spojrzalem w kod. O destruktorze przeczytaj oczywiscie ale to:

[CODE]for (int i = 0; i < 50000; i++){
rowcount = model->rowCount();
//wypełnianie modelu przez QStandardItem
model->setItem(rowcount,0,itemMark = new QStandardItem("jakas wartosc"));

Zawsze dodajesz wartosci do tej samej pozycji? 50 tysiecy razy? na pewno nie chciales zamiast rowcount do funkcji setitem przekazac "i" jako pierwszy argument? Nastepuje wyciek pamieci. Przydzielasz pamiec dla 49 999 x 6 niepotrzebnych standard itemow. One wyladuja w pamieci ale tracisz do nich dostep. Dostep masz tylko do jednego. Podstawy, banal. Popraw. Pała.


Zero litości dla nieróbstwa.
edytowany 1x, ostatnio: Malootki, 2011-11-13 06:15

Pozostało 580 znaków

2011-11-13 12:48
0

Dzięki na nakierownie gdzie jest problem, ale teraz do końca nie wiem jak go rozwiązać.
Czyli mam nie tworzyć nowych QStringItems tylko wszystko przetrzymywać w jednym? Jak? Czy może zrobić jakąś listę tych itemów?

Zielony jestem z obiektowości, a już z zarządzania pamięcią to już totalnie, dlatego będe wdzięczny za każdą pomoc.

edytowany 1x, ostatnio: Miszcz_, 2011-11-13 12:51

Pozostało 580 znaków

2011-11-13 15:15
qtMaster
0
Miszcz_ napisał(a)

Zielony jestem z obiektowości, a już z zarządzania pamięcią to już totalnie, dlatego będe wdzięczny za każdą pomoc.

to się nie bierz za Qt skoro nie masz podstaw.

Pozostało 580 znaków

2011-11-13 16:32
0

W jakimś frameworku muszę sie tych podstaw nauczyć.

Nawet w dokumentacji Qt jest jak byk napisane, że dokumentacja i sam framework są dla ludzi, którzy znają c++ na solidnym obiektowym poziomie. - several 2011-11-13 23:30

Pozostało 580 znaków

2011-11-13 21:33
qtMaster
0
Miszcz_ napisał(a)

W jakimś frameworku muszę sie tych podstaw nauczyć.
więc wybierasz framework, który rozszerza język o niestandardowe mechanizmy. Dlatego tworzysz ten temat i dlatego masz takie problemy bo zabierasz się za naukę od złej strony.

Pozostało 580 znaków

2011-11-14 11:35
0

Miszczu_,żeby swobodnie operować w Qt musisz wiedzieć:

1.Mechanizm polimorfizmu musisz mieć w małym palcu.
2.To samo jeśli chodzi o wskaźniki.
3.Dobrze znać się na dziedziczeniu,reimplementacji funkcji z klasy bazowej oraz wywoływaniu wersji funkcji z klasy bazowej.
4.Bardzo ułatwi ci życie znajomość szablonów,a kontenerów w szczególności.
Te punkty głównie są potrzebne z dobrej znajomości C++.

5.Mieć orientację na temat komunikatów systemu wysyłanych do twojej aplikacji.
6.Orientować się w okienkowym systemie operacyjnym-żebyś się nie drapał w głowę jak ci przyjdzie robić dialog modalny albo niemodalny,tudzież zajmować się obszarem roboczym okna.

Jeśli na wszystkie punkty możesz odpowiedzieć mocnym tak,wtedy jest sens kontynuacji nauki Qt.


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB, 2011-11-14 11:36

Pozostało 580 znaków

2011-11-15 11:47
1

Problemem jest:

Miszcz_ napisał(a)

... (w menedzeże pokazuje, że usuwa niecałe 2 mega z 50mb które ta klasa stworzyła)...

To nie jest obiektywna miara użycia pamięci przez twój kod!
Standardowa biblioteka zarządzająca stertą, nie zwraca systemowi pamięci natychmiast po wywołaniu delete. W ramach optymalizacji ta pamięć jest zachowywana na później (jest duże prawdopodobieństwo, że program znowu będzie potrzebował tą pamięć).

Potrzebujesz narzędzia do testowania zarządzania pamięcią. Pod Linux'em jest Valgrind. DUMA (wersja Electric Fance) jest dostępna pod Win32 i pod Linux.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2011-11-15 22:39
0
MasterBLB napisał(a)

Miszczu_,żeby swobodnie operować w Qt musisz wiedzieć:
....
...
Jeśli na wszystkie punkty możesz odpowiedzieć mocnym tak,wtedy jest sens kontynuacji nauki Qt.

Cóż dopiero wszedłem w obiektowość, i na każdy punkt odpowiadam: nie :)
QT akurat wybrałem bo wszędzie pisze, że jest fajny rozbudowany, przenaszalny itd, poza tym co innego pod Linuksem. Nie miałem pojęcia, że jest tak zakręcony i, że wymaga takiej wiedzy. Choć w sumie na swoje potrzeby na razie go ogarnąłem. No, ale dostosuje się do rad i w następnym projekcie zmienię frameworka. Tylko na co?

edytowany 1x, ostatnio: Miszcz_, 2011-11-15 22:39

Pozostało 580 znaków

2011-11-16 02:37
qtMaster
0

dla ciebie jak na razie najlepszym 'frameworkiem' będzie c++ + stl. Dzięki temu poznasz mechanizmy obiektowe, szablony, nauczysz się wykorzystywać kontenery oraz zarządzać poprawnie pamięcią (a w c++ to nie zawsze jest fajna sprawa). Warto później troszkę poczytać sobie o boost, poklepać sobie w tym coś i w między czasie powoli wdrażać się w Qt. Po takiej drodze Qt powinno być dla ciebie przyjazne, zrozumiale i być może genialne w swojej organizacji. Póki co przypuszczam, że jest zawiłe, skomplikowane, mało przyjazne, ale na pewno efektowne.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0