double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set
-
Given the following fragments of code :
class MyDialog : public QDialog { ... }; MyDialog::~MyDialog() { qInfo() << "~MyDialog()"; }
and
// scope begins MyDialog d; d.setAttribute( Qt::WA_DeleteOnClose, true ); int result = d.exec(); qInfo() << "After exec"; // scope ends
I get the following output
~MyDialog()
double free or corruption (out)
Aborted (core dumped)
Without
d.setAttribute( WA_DeleteOnClose, true );
everything is fine and expected.NOTE : I know that there is no need to use the delete on close in this case as the dialog deletes when leaving the scope. I also don't need for a "better solution" etc (I've read a lot of posts on SO and Qt Centre Forum with such irrelevant answers). The question is Why the error occurs at the first time the
~QDialog()
is called ? And maybe Am I right that the error occurs at the first time the~QDialog()
is called?
I suspect that the
deleteLater()
function is not allowed to be called on a stack variable but to confirm I (probably) need to go through theQCoreApplication::postEvent()
function which is too complicated to me as a user and not a Qt-developer.
Sorry if it is a stupid question :)
-
@LRDPRDX you're right.
it's more sinister.
the QDialog implementation of delete on close is a
delete this
call. 😱 very naughty, even if allocated on the heap.so its not double free call, it's corruption.
class MyPDialog : public QDialog { public: MyPDialog(QWidget *parent = nullptr) : QDialog(parent) {} void deleteOnClose() {delete this;} ~MyPDialog() { qInfo() << "~MyPDialog()"; } }; int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); MyPDialog d; d.deleteOnClose(); // d.setAttribute( Qt::WA_DeleteOnClose, true ); // int result = d.exec(); qInfo() << "After exec" /*<< result*/; return app.exec(); }
-
@LRDPRDX said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
Why the error occurs at the first time the ~QDialog() is called ?
I don't think it happens in the destructor. It happens after the destructor, when Qt::WA_DeleteOnClose causes the second delete.
-
I don't hink its unexpected,
you see the first deletion in your console output
~MyDialog()
after that the program tries to call delete the object that is already deleted.
-> the destructor is of course not called again (no instance to call it upon) but you get the double free exception
-
@LRDPRDX you're right.
it's more sinister.
the QDialog implementation of delete on close is a
delete this
call. 😱 very naughty, even if allocated on the heap.so its not double free call, it's corruption.
class MyPDialog : public QDialog { public: MyPDialog(QWidget *parent = nullptr) : QDialog(parent) {} void deleteOnClose() {delete this;} ~MyPDialog() { qInfo() << "~MyPDialog()"; } }; int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); MyPDialog d; d.deleteOnClose(); // d.setAttribute( Qt::WA_DeleteOnClose, true ); // int result = d.exec(); qInfo() << "After exec" /*<< result*/; return app.exec(); }
-
@J-Hilk said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
it's more sinister.
There's nothing sinister, the OP already provided the answer.
@LRDPRDX said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
I suspect that the deleteLater() function is not allowed to be called on a stack variable but to confirm I (probably) need to go through the QCoreApplication::postEvent() function which is too complicated to me as a user and not a Qt-developer.
No, delete is not allowed on a stack variable. You don't need to be a Qt developer to know this, and it has nothing to do with how you call the
delete
-- from the outside, from the inside (i.e. deleting this), through a custom event or without. -
@kshegunov said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
No, delete is allowed on a stack variable
Do you perchance mean
delete
is not allowed on a stack variable?Oh, you updated your post after I posted this :)
-
@JonB said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
Do you perchance mean delete is not allowed on a stack variable?
Indeed, it was a typo.
-
@kshegunov
A "typo" is a misspelling, not a complete reversal of a comment's intention! :DAnd I agree it's about time somebody said you just must not delete a stack variable, period. [Whether
WA_DeleteOnClose
docs might mention that is what this does, and so should only be used on heap instances, is another matter. I was never clear just what exactlyWA_DeleteOnClose
did, though I used it. -
@kshegunov said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
There's nothing sinister, the OP already provided the answer.
no matter what, telling a class to commit suicide is sinister in my books :P
-
@JonB said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
A "typo" is a misspelling, not a complete reversal of a comment's intention! :D
I added the comma after the fact, which introduced the missing negation, so *shrug* happens.
@J-Hilk said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
no matter what, telling a class to commit suicide is sinister in my books :P
Your books are wrong. We are a free-haven! ;)
-
@kshegunov said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
I added the comma
-
-
@kshegunov said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
You don't need to be a Qt developer to know this, and it has nothing to do with how you call the delete -- from the outside, from the inside (i.e. deleting this), through a custom event or without.
Agreed, but how do I know what the
Qt::WA_DeleteOnClose
actually does? One can guess it causes the call ofdelete
on the variable but that was just not enough to me to be sure (and obviously I was looking for an answer in the wrong place in the source code). Anyway, now I've got the answer. Thank you. -
@LRDPRDX said in double free or corruption (out) when closing a QDialog with the WA_DeleteOnClose attribute set:
Agreed, but how do I know what the Qt::WA_DeleteOnClose actually does?
If you feel the name doesn't give it up, or isn't clear enough, I'd've suggested looking up in the documentation:
https://doc.qt.io/qt-5/qt.html#WidgetAttribute-enumIt's sort of the point of having documentation - so you don't need to go browsing through the code, and thankfully Qt has the best one I've ever seen.