为什么我在 Qt 中继承 QWidget class 时会发生内存泄漏

why do i have memory leak while doing inheritance of QWidget class in Qt

我是 C++ 新手。我正在尝试通过继承基础 class QWidget 来设计一个 class 但是我在通过 new 创建 class 时出现内存泄漏。 下面是我的代码片段 class 和主应用程序

#include "QWidget"
#include "QDebug"
#include "ui_myobject.h"

namespace Ui {    
    class MyObject;    
}

class MyObject : public QWidget{    
    Q_OBJECT    
public:       
    explicit MyObject();
    ~MyObject();
    Ui::MyObject *ui; 
};

#include "myobject.h"
#include "ui_myobject.h"

MyObject::MyObject() : QWidget(),ui(new Ui::MyObject){    
    ui->setupUi(this);
    qDebug() << "MyObject Initilised";
}
MyObject::~MyObject(){    
    delete ui;
    qDebug() << "MyObject Deinitilised";    
}

class Application : public QWidget
{
    Q_OBJECT    
public:
    explicit Application(QWidget *parent = 0);    
    ~Application();     
    MyObject *m_MyObject;       
};  

Application::Application(QWidget *parent) :QWidget(parent),ui(new Ui::Application){    
ui->setupUi(this);    
}    

我通过按钮的点击释放槽调用下面的函数

void somefunction()
    {
      m_MyObject = new MyObject();
                //mAlarm_main->Alarm();    
                m_MyObject->show();    
                delete m_MyObject;
    }


int main(int argc, char *argv[])
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
    ; // Qt5 uses different graphical backend
#else
    QApplication::setGraphicsSystem("raster");
#endif

    QApplication a(argc, argv);
    Application w;

    // uncomment this line to remove window frame
    //w.setWindowFlags(Qt::FramelessWindowHint);

    w.setGeometry(0,0,800,480);

    w.show();

    return a.exec();
}

当我调用某个函数时,我的应用程序出现内存泄漏,我正在使用 top 命令观察它的堆栈大小,它在 200 times 我的应用程序崩溃后不断增加 2 mb。我正在删除我的对象,但仍然发生一些内存泄漏是否有任何不同的方法来删除 QWidget

如果我不调用 m_MyObject->show();函数比内存泄漏不会发生。

在下面的代码中,您删除了刚刚显示的小部件(方法“show”没有阻塞)。我相信它会导致未定义的行为,并且可能会导致您担心的内存泄漏:

  m_MyObject = new MyObject();
  m_MyObject->show();
  delete m_MyObject;

假设你一次只需要一个MyObject,我建议只创建一次MyObject(不要忘记默认用nullptr初始化)

if (!m_MyObject)
    m_MyObject = new MyObject();
m_MyObject->show();

另一种方式(看起来这个小部件应该显示为单独的 window)是设置 Qt::WA_DeleteOnClose attribute (see QWidget::close 以获取详细信息)。

    m_MyObject = new MyObject();
    m_MyObject->setAttribute(Qt::WA_DeleteOnClose, true);
    m_MyObject->show();

示例:

#include <QApplication>
#include <QPushButton>

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

    QWidget* w = nullptr;
    QPushButton b;
    b.setText("Button");
    b.connect(&b, &QPushButton::clicked, [&w]() {
        w = new QWidget();
        w->setAttribute(Qt::WA_DeleteOnClose, true); // ADD THIS LINE
        w->show();
        // delete w; // DON'T DO IT
    });
    b.show();

    return app.exec();
}