Delete obiektu, Qt

0

Witam. Qt.
Pewnie zapytam o jakąś oczywistość, ale nie znalazłem konkretnej odpowiedzi w sieci na pytanie które chcę zadać ( albo nie wiedziałem, która jest właściwa i po prostu nie zwróciłem na nią uwagi).
Nie jest mi to absolutnie potrzebne do działania programiku który robię ( bo działa), ale chciałbym wiedzieć "dlaczego tak".
Do rzeczy ( do pytania jest ważna tylko ostatnia część).
Piszę sobie gierkę planszową i używam tam obiektów QLineF do wyznaczenia sobie toru pocisku pod kątem ( droga może być linią łamaną poprzez kilka węzłów, nie chcę się w to zagłębiać, ale ważne jest to, że wyznaczam sobie najkrótszą drogę pocisku, więc robię kilka obiektów QLineF do porównywania długości drogi-> wtedy wybieram najkrótszą).

 
   QLineF mojaNajkrotszaLinia;//taka nazwa na potrzeby forum
   mojaNajkrotszaLinia.setLine(0,0,1000,1000);//nadanie początkowej długości linii, żeby warunek z if mógł zostać spełniony

    //utworzenie np. 4 QLineF pomiędzy środkiem jednostki gracza oraz węzłami
    for (size_t i=0, n=4; i<n; i++){
    QLineF *line = new QLineF(0,0,100,100);//wpisałem sobie stałe, bo cały konstruktor jest dosyć długi- pobiera długości z innych obiektów ( węzłów) z innych klas oraz współrzędne ich środków- wstawiłem taki, żeby nie robić spagetti

    //dopasowanie najkrótszej trasy poprzez porównanie dlugosci mojaNajkrotszaLinia oraz line
    if (line->length()<mojaNajkrotszaLinia.length()){
           mojaNakrotszaLinia.setLine(line->x1(),line->y1(),line->x2(),line->y2());
        }

    //PYTANIE
    //usuniecie line ( byla tylko na potrzeby sprawdzenia czy moze trasa bedzie krotsza)
    delete line;
    qDebug()<<line->length(); (poprawka)
    }
//dalej jakis kod

moje pytanie-> po usunięciu line za pomocą delete, wciąż mogę wywołać qDebug() z odniesieniem do line ( która została już usunięta). Oczywiście wynik który otrzymuję to "0". Pytanie, dlaczego nie dostaję żadnego błędu o odniesieniu do obiektu który został usunięty i mogę zażądać wykonania na nim operacji typu (poprawka)line->length(); itp? Gdyby ktoś mógł rzucić jednym zdaniem i oświecić nieprogramistę:)

0

Pamięć jest zwalniana, ale nie znaczy to że jest czyszczona.

#include <QDebug>

class Test{
public:
    int a;
    char buf2[1024];
};

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

    Test * test = new Test();

    test->a = 2;
    delete test;

    qDebug() << test->a;

    return 0;
}

Zwraca "2". lecz po zakomentowaniu buf2, wartość pokaże się inna, bo już zdąży się nadpisać przez "kogoś" innego.

Głowy nie dam uciąć :P

2

Twój kod się nie skompiluje (qDebug() << line.length nie ma sensu gdy line jest wskaźnikiem).

Dereferencja wskaźnika po delete (albo ogółem niewskazującego na poprawny obiekt) jest UB. Może zadziałać jak chcesz, może sformatować komputer, może zarazić Cię świńską grypą.

Przy okazji: Jeśli możesz używaj obiektów tego typu przez wartość, a jak nie to unique_ptr > shared_ptr > > > > T*

2

Jest tak że zwolnienie obiektu (delete), nie czyści po nim pamięci. Odwołując się do tej pamięci możesz mieć... wszystko :-) Albo zadziała, albo nie, albo wybuchnie albo nie albo... będzie "totalny shiz z aplikacją". Dość powiedzieć że to Undefined Behavior i tyle ..

A co do szczegółów dla Qt...

Ech.. Dla Qt sprawa jest dość rozbudowana. Masz tu przyjętą filozofię zarządzania obiektami:

Na stercie z podaniem rodzica:

QTimer* timer = new QTimer(this);

To rodzic zajmie się usunięciem dziecka z pamięci.

Na stosie bez podania rodzica
Np. QFile, QApplication lub widgety najwyższego poziomu ... QWidget, QMainWindow....

Na stosie - obiekty typu Value
QString, QStringList, QColor...

Stos lub sterta - w zależności od czasu życia
Hmm... np QDialog w zależności od tego kiedy chcesz aby go zniszczono.

Do tego dochodzi jeszcze:

  1. deleteLater() które usunie obiekt w zależności od pracy pętli zdarzeń http://doc.qt.io/qt-5/qobject.html#deleteLater
  2. Wskaźniki inteligentne typu QPointer czyli QScopedPointer (to nie jest wbrew pozorom unique_ptr z biblioteki std bo nie ma move), QSharedPointer, QWeakPointer które usuną (lub nie) obiekt po zajściu warunków dla nich właściwych
  3. Sygnał destroyed(...) który może przekazać wskaźnik niszczonego obiektu
  4. Pewnie inne szczegóły o które jak zapytasz do dostaniesz odpowiedź...

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