应用Singleton-Paterrn后退出主窗口时出现_CrtIsValidHeapPointer(block)错误

时间:2017-08-25 02:04:32

标签: c++ qt

我正在Windows上开发一个Qt桌面应用程序。在主窗口中,我需要在我的Tab Widget中添加一个小部件,它通常写在下面:

void MainWindow::setConfParas()
    {
        ConfParas *confparas=new ConfParas();
        ui->TabWidget->addTab(confparas,"Configure Parameters");
    }

我正在尝试将Singleton Pattern应用到我的ConfParas类中,它设计得像这样

class ConfParas : public QWidget
{
    Q_OBJECT

public:
    static ConfParas* getInstance()
    {
        static ConfParas theConfParas;
        return &theConfParas;
    }
    explicit ConfParas(QWidget *parent = 0);
    ConfParas(const ConfParas&)=delete;
    ConfParas& operator=(const ConfParas&)=delete;
    //sth else...
}

以前的代码将写成:

void MainWindow::setConfParas()
    {
        ConfParas *confparas=ConfParas::getInstance();
        ui->TabWidget->addTab(confparas,"Configure Parameters");
    }

并且编译器没有发出任何错误消息,我可以轻松启动应用程序,但是当我关闭主窗口时, _CrtIsValidHeapPointer(阻止)错误被提出了! 所以我猜它发生在主窗口解构的时期。

1 个答案:

答案 0 :(得分:1)

当您将指针传递给QObject时,Qt将接管该指针的生命周期。它假设内存是动态分配的,然后在解除分配时调用delete。此规则的一个例外是子项在其父项之前被销毁。

请参阅https://doc.qt.io/archives/4.6/objecttrees.html

您的静态成员在堆栈上声明,并由运行时管理。当您将其传递给QObject时,您要求进行双重删除。也就是说,您致电QTabWidget::AddTab,将所有权委托给QTabWidget。这个QTabWidget,一个非静态变量将在任何静态变量(你的QWidget)之前被销毁。由于它是父项,因此它也会删除其子项(您的QWidget),然后当main结束时,它还会调用static QWidget的析构函数,因此会进行双重删除。

如果你的静态成员是第一次调用时分配的指针,那么你就不会遇到这个问题。事实上,我知道一些开发人员会说这不是一个真正的问题(不是说我同意他们),因为在拆除建筑物之前清洁建筑物的重点是什么?