Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Widget with nested Layout crashes in destructor
Forum Updated to NodeBB v4.3 + New Features

Widget with nested Layout crashes in destructor

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 780 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Fabian_Schmidt
    wrote on last edited by
    #1
    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.

    kshegunovK 1 Reply Last reply
    0
    • F Fabian_Schmidt
      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.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      @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 implementation outerLayout is destroyed before innerLayout, however because outerLayout is the owner of innerLayout it will try to delete it. Two problems with this:

      1. Auto-storage (stack) variables can't be deleted
      2. 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 up innerLayout 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 the QObject model to clean up on destruction.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      3
      • F Offline
        F Offline
        Fabian_Schmidt
        wrote on last edited by Fabian_Schmidt
        #3

        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.

        kshegunovK 1 Reply Last reply
        0
        • F Fabian_Schmidt

          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.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @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.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved