Widget with nested Layout crashes in destructor
-
class LayoutTest : public QLabel { public: LayoutTest(); private: QHBoxLayout innerLayout; QVBoxLayout outerLayout; }; LayoutTest::LayoutTest() { setLayout(&outerLayout); outerLayout.addLayout(&innerLayout); }
This leads to a crash in the destructor, however
class LayoutTest : public QLabel { public: LayoutTest(); private: QHBoxLayout innerLayout; QVBoxLayout *outerLayout; }; LayoutTest::LayoutTest() { outerLayout = new QVBoxLayout(); setLayout(outerLayout); outerLayout->addLayout(&innerLayout); }
This however works fine. Why does it work when I allocate the outer layout dynamicaly? Both ways seem to me like the objects should be cleaned up correctly.
-
class LayoutTest : public QLabel { public: LayoutTest(); private: QHBoxLayout innerLayout; QVBoxLayout outerLayout; }; LayoutTest::LayoutTest() { setLayout(&outerLayout); outerLayout.addLayout(&innerLayout); }
This leads to a crash in the destructor, however
class LayoutTest : public QLabel { public: LayoutTest(); private: QHBoxLayout innerLayout; QVBoxLayout *outerLayout; }; LayoutTest::LayoutTest() { outerLayout = new QVBoxLayout(); setLayout(outerLayout); outerLayout->addLayout(&innerLayout); }
This however works fine. Why does it work when I allocate the outer layout dynamicaly? Both ways seem to me like the objects should be cleaned up correctly.
@Fabian_Schmidt said in Widget with nested Layout crashes in destructor:
Switch the order of the members:QVBoxLayout outerLayout; QHBoxLayout innerLayout;
Or better yet create them in the heap, as you're losing ownership by adding them to a parent anyway.
Why does it work when I allocate the outer layout dynamicaly?
Order of destruction matters.
In your current implementationouterLayout
is destroyed beforeinnerLayout
, however becauseouterLayout
is the owner ofinnerLayout
it will try to delete it. Two problems with this:- Auto-storage (stack) variables can't be
delete
d - Stack unwinding will want to call the destructor of
innerLayout
, but at that time the object is already invalid.
Children will notify parent of destruction, but when
outerLayout
is cleaned upinnerLayout
isn't yet destroyed. To avoid this kind of issue the conventional advice is to declare the parent-child relationship at initialization time and not change it afterwards. Or to just create the objects in the heap and rely on theQObject
model to clean up on destruction. - Auto-storage (stack) variables can't be
-
Makes sense. Would you say that constructing objects on the heap is a better style of programming when writing Qt apps?
Your answer is definitely correct though I forgot that objects are destroyed in reverse order of declaration. I would mark this as solved but I don't see the button. -
Makes sense. Would you say that constructing objects on the heap is a better style of programming when writing Qt apps?
Your answer is definitely correct though I forgot that objects are destroyed in reverse order of declaration. I would mark this as solved but I don't see the button.@Fabian_Schmidt said in Widget with nested Layout crashes in destructor:
Would you say that constructing objects on the heap is a better style of programming when writing Qt apps?
No I wouldn't. Different cases warrant different approaches, and heap allocations aren't free of charge. Especially relevant, if you take into account that Qt already uses the d-ptr idiom, meaning you already have one
new
for each object you create; no matter how you create it. You just have to pay attention to what object owns what object.I would mark this as solved but I don't see the button.
At the bottom of the page, the "Topic tools" button.