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

3

0

Given the following fragments of code :

class MyDialog : public QDialog
{
    ...
};

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

and

// scope begins
MyDialog d;
d.setAttribute( 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 these 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?

Worsted answered 7/11, 2021 at 14:57 Comment(0)
W
2

I've got the answer in the Qt Forum : link.

The source code for the QDialog class contains the following lines:

//QDialog::exec()

if (deleteOnClose)
    delete this;
return res;

which is, ofc, causes a crash if this points to a stack object.

Worsted answered 8/11, 2021 at 14:2 Comment(1)
Correct. And since it's a dialog, the dialog closes before returning to the caller. In turn, that means the on-close delete this happens before the caller does unwinds its stack. So that explains why it crashes, although not really in ~QDialog but more in operator delete. But IIRC GCC tends to inline the latter into the former.Faille
H
0

Try this instead:

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

Either new QobjectDerived or new QobjectDerived(this) for dynamic allocation and then the dynamic deallocation could finalize the object destruction just once. That attribute WA_DeleteOnClose set is obviously provoking internal delete when the dialog getting closed but no second destructor call as in case with that object allocated on stack.

Haberdasher answered 7/11, 2021 at 16:32 Comment(6)
Sorry, but what do you mean under the second destructor call? If I understand correctly you mean that the delete operator called on an invalid "stack pointer" ?Worsted
BTW. Your "try this instead" code, ofc, works. But I want to know why my code crashes. I tried to go through the source code for QObject but it seems that the delete logic is in the postEvent function which is too complicated to me.Worsted
Whenever the object is allocated on the stack as in your original code we have the destructor called after the code execution leaves the object scope at all times. Not the case with dynamic allocation with which the destruction happening depending on when delete operator executes the destructor for that object.Haberdasher
No double destructor call is allowed.Haberdasher
Sorry, I don't see how your words answer the question. Obviously (?), the error occurs when the exec() returns --- not at the end of scope.Worsted
I mean I understand (as I think) that the error is caused by trying to delete the dialog as it closes. But I don't know how it crashes.Worsted
F
0

You're creating an object on the stack and then try to delete it with delete (indirectly via the WA_DeleteOnClose - flag). I don't see why you would not get a double delete then.

Flawy answered 7/11, 2021 at 16:32 Comment(3)
When the second deletion occurs?Worsted
When you create an object on the stack it gets destroyed as soon as the scope of the object goes out of scope.Flawy
But as I said in the post : the error occurs before leaving the scope.Worsted

© 2022 - 2024 — McMap. All rights reserved.