Reputation: 32645
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
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
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
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
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
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