Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.0.0
-
None
Description
Signal-Slot connections between QObjects handle lifetimes gracefully. When either goes out of scope, the connection is removed.
QProperties do handle this only in one way. If the receiver of data goes out of scope, it unregisters from the sender. However, it does not work the other way. When the sender goes out of scope, the receiver might still try to access it.
We should document that it is the developers' responsibility to make sure senders outlive their dependent receivers.
We might even solve this problem: Each binding could get a "broken dependency" flag in addition to the "dirty" flag. When a property goes out of scope, it could set the broken dependency flag in all properties which depend on it. When a property is read which has the broken dependency flag set, we could error out.
Some code for illustration:
#include <QObject> #include <QDebug> int main(){ { QProperty<int>* a = new QProperty<int>(1); QProperty<int>* b = new QProperty<int>(2); b->setBinding([&a](){ return a->value(); }); *a = 3; delete b; // deleting the receiver is not a problem, it unregisters with the sender *a = 4; delete a; } { QProperty<int>* a = new QProperty<int>(1); QProperty<int>* b = new QProperty<int>(2); b->setBinding([&a](){ return a->value(); }); *a = 3; delete a; // deleting the sender is a problem qDebug() << b->value(); // here use-after-free: a is read delete b; } }