设置了“WA_DeleteOnClose”属性的堆栈 QDialog 上出现“双重释放或损坏(输出)”错误

`double free or corruption (out)` error on a stack QDialog with the `WA_DeleteOnClose` attribute set

给定以下代码片段:

class MyDialog : public QDialog
{
    ...
};

MyDialog::~MyDialog()
{
    qInfo() << "~MyDialog()";
}

// scope begins
MyDialog d;
d.setAttribute( WA_DeleteOnClose, true );
int result = d.exec();
qInfo() << "After exec";
// scope ends

我得到以下输出

~MyDialog()

double free or corruption (out)

Aborted (core dumped)

没有 d.setAttribute( WA_DeleteOnClose, true ); 一切都很好,符合预期。

注意:我知道在这种情况下不需要使用关闭时删除,因为对话框会在离开范围时删除。我也不需要“更好的解决方案”等(我已经阅读了很多关于 SO 和 Qt 中心论坛的帖子,其中包含这些不相关的答案)。问题是 为什么错误发生在 第一次 调用 ~QDialog() 时? 也许 我说得对吗第一次调用 ~QDialog() 时发生错误?

试试这个:

MyDialog* d = new MyDialog;
d->setAttribute( WA_DeleteOnClose, true );
int result = d->exec();

new QobjectDerivednew QobjectDerived(this) 进行动态分配,然后动态释放可以完成一次对象销毁。当对话框关闭但没有第二次析构函数调用时,该属性 WA_DeleteOnClose 设置显然会引发内部 delete,就像在堆栈上分配该对象的情况一样。

您正在堆栈上创建一个对象,然后尝试使用 delete 删除它(间接通过 WA_DeleteOnClose - 标志)。我不明白你为什么 得到双重删除。

我在 Qt 论坛中找到了答案:link

QDialog class 的源代码包含以下几行:

//QDialog::exec()

if (deleteOnClose)
    delete this;
return res;

也就是说,如果 this 指向堆栈对象,ofc 会导致崩溃。