此代码是否提供内存泄漏?

Mik*_*ail 4 c++ qt valgrind memory-leaks

最后我安装了Ubuntu并设置了Qt + Valgrind来防止内存泄漏,这是我在Windows中无法做到的.所以我无法理解这段代码是否提供内存泄漏?事实上,Valgrind说我只有500多个问题,但没有泄漏.一世

#include <QWidget>
#include <QFrame>
#include <QVBoxLayout>
#include <QApplication>

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

{
    QApplication a(argc, argv);

    QWidget * wdgt = new QWidget;  //this line should be the cause of leakage 
                                   //if it exist (as far as i know)
    QVBoxLayout *layout = new QVBoxLayout;
    QFrame * frame = new QFrame;

    frame->setFrameStyle(QFrame::Panel | QFrame::Plain);
    frame->setLineWidth(5);
    layout->addWidget(frame);

    wdgt->setLayout(layout);
    wdgt->setFixedSize(800,600);
    wdgt->show();

    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

jpo*_*o38 8

请参阅此文章:创建和取消分配Qt窗口小部件对象

它解释了如果一个Qt对象有一个父对象,它将在父对象被销毁时自动删除.

在你的代码中:

  • wdgtlayout你的父母,因为你做到了wdgt->setLayout(layout).
  • wdgtframe你的父母,因为你做了layout->addWidget(frame),layout父母是wdgt.如thuga评论,布局将所有权传递给他们自己的父母.

在您的代码中,只有wdgt孤儿(没有Qt父级自动删除它).

要解决这个问题,你可以给他一个父母:

QWidget * wdgt = new QWidget(&app);
Run Code Online (Sandbox Code Playgroud)

因此,这wdgt是一个孩子,app然后在app销毁时自动删除.

或者自己删除:

int main(int argc, char *argv[])
{
    ...
    int res = a.exec();
    delete wdgt; // this will delete wdgt, but also frame and layout
    return res;
}
Run Code Online (Sandbox Code Playgroud)

或者,fianlly,将其创建为对象,以便在超出范围时将其删除:

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

    QWidget wdgt;

    QVBoxLayout *layout = new QVBoxLayout;
    QFrame * frame = new QFrame;

    frame->setFrameStyle(QFrame::Panel | QFrame::Plain);
    frame->setLineWidth(5);
    layout->addWidget(frame);

    wdgt.setLayout(layout);
    wdgt.setFixedSize(800,600);
    wdgt.show();

    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,请注意,如果你这样做QVBoxLayout *layout = new QVBoxLayout(wdgt),则没有必要这样做wdgt->setLayout(layout).所以这两段代码是等价的:

QVBoxLayout *layout = new QVBoxLayout(wdgt); // parenting upon construction
Run Code Online (Sandbox Code Playgroud)

是相同的:

QVBoxLayout *layout = new QVBoxLayout; // no parent
wdgt->setLayout( layout ); // reparenting
Run Code Online (Sandbox Code Playgroud)