开发者

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?


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.


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


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.


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());


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜