2009-10-30 24 views
14

Szukałem na przykład Qt here:Qt: czy "nowy bez usuwania" powoduje przecieki pamięci za pomocą elementów sterujących?

i wewnątrz konstruktora, mają:

Window::Window() 
{ 
    editor = new QTextEdit(); // Memory leak? 
    QPushButton *sendButton = new QPushButton(tr("&Send message")); // Memory leak? 

    connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); 

    QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak? 
    buttonLayout->addStretch(); 
    buttonLayout->addWidget(sendButton); 
    buttonLayout->addStretch(); 

    QVBoxLayout *layout = new QVBoxLayout(this); // Memory leak? 
    layout->addWidget(editor); 
    layout->addLayout(buttonLayout); 

    setWindowTitle(tr("Custom Type Sending")); 
} 

te linie z komentarzami

// Memory leak? 

nie są te przecieki pamięci?

Jeśli tak, ponieważ klasa okna nie ma konstruktora, powinienem utworzyć wszystkie te zmienne (edytor już jest) Zmienne elementu okna?

Lub ... czy Qt wewnętrznie "usuwa" te zmienne składowe, gdy wykracza poza zakres?

Odpowiedz

25

Nie, funkcja addWidget() zachowa prawo własności do widżetu. Następnie zniszczy widżety, które posiada.

Dodatkowo można przeczytać here że:

Jak z QObjects, QWidgets mogą być tworzone z obiektów nadrzędnych do wskazują własności, zapewniając, że obiekty są usuwane, gdy nie są one już używane. W przypadku widgetów te relacje nadrzędny-podrzędny mają dodatkowe znaczenie: Każdy widżet podrzędny jest wyświetlany w obszarze zajmowanym przez jego widget nadrzędny. Oznacza to, że po usunięciu widgetu okna wszystkie znajdujące się w nim widżety podrzędne również zostaną usunięte.

+0

+1 Zgaduję w usuniętej odpowiedzi :) – AraK

7

Jeśli istnieje wyjątek zgłoszony między new i addWidget, to tak, istnieje przeciek pamięci. W przeciwnym razie nadrzędna kontrola przejmuje na siebie własność pamięci.

QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak? 
//make sure you don't throw here 
buttonLayout->addWidget(sendButton); 
5

Oprócz prawidłowej odpowiedzi Klaim za:

chciałbym przechowywać te wskaźniki w std::auto_ptr tymczasem przekazać je do rodzica.

std::auto_ptr<QHBoxLayout> buttonLayout(new QHBoxLayout()); 
// make things which could throw... 
layout->addLayout(buttonLayout.release()); 

W ten sposób na pewno nie będziesz mieć przecieków.

+0

Jeszcze lepiej niż moja własna odpowiedź –

+0

Czy nie zostanie ona dwukrotnie usunięta, jeśli to zrobisz? Raz przez auto_ptr, a następnie ponownie przez QObject? – James

+2

Zastąp std :: auto_ptr przez std :: unique_ptr ... – Klaim

0

Nie zostanie podwójnie usunięty z powodu wywołania .release().

Uwaga std :: unique_ptr zastępuje std :: auto_ptr. Mam nadzieję, że QT będzie obsługiwać semantykę ruchu, a wtedy release() będzie zamiast layout-> addLayout (std :: move (buttonLayout)) i bez wywoływania wywołania pojawi się błąd kompilacji.

+1

to shared_ptr, który zastępuje auto_ptr, unique_ptr jest przeznaczone tylko dla ograniczonych zakresów ptr nie do udostępniania, co oznacza, że ​​jest idealny do tej pracy, ponieważ nie chcemy jej udostępniać. –

Powiązane problemy