[英]_BLOCK_TYPE_IS_VALID_ and CrtIsValidHeapPointer assertion errors after int main() return stmt
[英]_CrtIsValidHeapPointer(block) error was raised when exit main window, after applied Singleton-Paterrn
我正在Windows上开发Qt桌面应用程序。在主窗口中,我需要向我的Tab窗口小部件中添加一个窗口小部件,通常如下所示:
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(block)错误 ! 所以我想这是在主窗口解构期间发生的。
当您将指针传递给QObject
,Qt将接管该指针的生命周期。 它假定内存是动态分配的,然后在需要取消分配时调用delete
。 此规则的例外情况是,如果一个子项在其父项之前被销毁。
请参阅https://doc.qt.io/archives/4.6/objecttrees.html
您的静态成员在堆栈上声明,并由运行时进行管理。 当您将其传递给QObject
,您会请求进行两次删除。 也就是说,您调用QTabWidget::AddTab
,它将所有权委派给QTabWidget
。 这个QTabWidget
,一个非静态变量将在任何静态变量(您的QWidget
)之前被销毁。 由于它是父级,因此还将删除其子级(您的QWidget
),然后在main
结束时还将调用您的static QWidget
的析构函数,从而进行两次删除。
如果您将静态成员设为在第一次调用时分配的指针,则不会有此问题。 实际上,我知道一些开发人员会说这根本不是问题(不是说我同意他们的意思),因为在拆除建筑物之前清洁建筑物有什么意义?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.