sivabudh
sivabudh

Reputation: 32645

Qt: does "new without delete" cause memory leaks with controls?

I was looking at Qt example here:

and inside the constructor, they have:

 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"));
 }

Those lines with comments

// Memory leak?

aren't those memory leaks?

If so, since the Window class has no constructor, then I should make all of those variables (editor already is) Window member variables ?

Or..does Qt internally "delete" those member variables when it goes out of scope?

Upvotes: 21

Views: 7104

Answers (5)

jfMR
jfMR

Reputation: 24788

As of C++14 you can use the std::make_unique() convenience function template for creating an std::unique_ptr<> that has exclusive ownership of the widget. Then, at the moment of passing the widget to addLayout(), you make the smart pointer give up ownership by calling release():

auto buttonLayout = std::make_unique<QHBoxLayout>(); 
// ...
// an exception could be thrown here
// ...
layout->addLayout(buttonLayout.release());

Upvotes: 2

Klaim
Klaim

Reputation: 69772

No, the addWidget() function will keep ownership of the widget. It will then destroy the widgets it owns.

Additionally you can read here that:

As with QObjects, QWidgets can be created with parent objects to indicate ownership, ensuring that objects are deleted when they are no longer used. With widgets, these parent-child relationships have an additional meaning: Each child widget is displayed within the screen area occupied by its parent widget. This means that when you delete a window widget, all the child widgets it contains are also deleted.

Upvotes: 31

Fernando N.
Fernando N.

Reputation: 6439

In addition to Klaim's correct answer:

I would store those pointers in a std::auto_ptr, meanwhile you pass them to their parent.

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

This way you are sure not to have leaks.

Upvotes: 6

Ben
Ben

Reputation: 9733

It won't get double deleted because of the .release() call.

Note std::unique_ptr is replacing std::auto_ptr. Hopefully QT will support move semantics then that release() would be instead layout->addLayout(std::move(buttonLayout)) and without the call to move, you'd get a compile error.

Upvotes: 0

Marcel Gosselin
Marcel Gosselin

Reputation: 4716

If there is an exception thrown between new and addWidget then yes there is a memory leak. Otherwise the parent control takes ownership of the memory.

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

Upvotes: 12

Related Questions