How to handle failures on construction?



  • Hi,

    I am concerned about resource leaks on construction; suppose that I have a widget that I am adding children to, and something throws an exception... will there be a leak of the child in the following situation?

    class X: public QWidget
    {
    public:
        X() : QWidget(nullptr)
        {
            QPushButton * b = new QPushButton ;
            b->setParent(this) ;
    
             // suppose something down here throws...
        }
    }
    
    // client code:
        X *x = nullptr  ;
        try
        {
            x = new X ;
        }
        catch (...) 
        {
            // ...
        }
    

    this is a simplified example with no layouts or anything, I guess the question boils down to whether or not the widget memory management cleanup for X will be called without a call to the destructor of X?

    [Edit: Added code tags -- @Wieland]


  • Qt Champions 2016

    Hi
    Nothing cleans up without the call to the dtor.
    but if u do QPushButton * b = new QPushButton(this) ; (or setParent)
    Then X will be deleted and all children.
    If X has no parents, it might be issue.
    Its a system.
    http://doc.qt.io/qt-5/objecttrees.html


  • Qt Champions 2016

    @Steve7b1 said in How to handle failures on construction?:

    I am concerned about resource leaks on construction; suppose that I have a widget that I am adding children to, and something throws an exception... will there be a leak of the child in the following situation?

    My advice - don't throw from the constructor. It's a bad habit in my opinion and you can easily go without it. As a side note Qt will not throw from the constructor, so any allocations you make are "safe".



  • @mrjj Hi,

    Thanks for your reply; I don't understand though why the child would be cleaned up in the example I gave, because the destructor isn't being called if we throw from within the constructor... could you expand a little?

    Steve.


  • Qt Champions 2016

    Hi
    QPushButton * b is owned by class X

    so when X is deleted then the childs are deleted too.

    Often Class X is owned by main window or other toplevel parent.
    So when its deleted, Class X is freed and so is button b.

    But yes, if Class X have no parent and u throw in ctor. then you got a leak :)
    "It cannot die, for it never lived." Kinda situation which can be avoided by not throwing in ctor.



  • @kshegunov Thanks for your reply. So would you suggest doing allocations with

    QWidget * p = new (std::nothrow) QWhatever(this) ;

    and then just checking the pointer value?

    Steve.


  • Lifetime Qt Champion

    @Steve7b1 Hi, do you have any condition in mind that would make one of your constructors throw an error ?



  • @SGaist I am mostly concerned about allocation failures; rare, but possible. I work on a system which is to do with visualisation of large datasets. Most of my usage is related to QGraphicsView and QGraphicsScene (not much like the example I gave, that was just hypothetical).

    Our users often leave sessions going for weeks, just closing their laptops and going home, so I have to maintain certain levels of paranoia...


  • Qt Champions 2016

    No, I suggest not throwing from the constructor (and ignoring the "out of memory" exception which you can do little to prevent). Also if you want to be throw-safe then don't use heap allocation (especially since in apps you're not concerned with binary compatibility). E.g.:

    class X: public QWidget
    {
        Q_OBJECT  //< Don't forget this one
    public:
        X(QWidget * parent = nullptr)  //< Pass on the parent, don't work against the framework!
            : QWidget(parent), b(this)
        {
             // Suppose something down here throws ...
             // ... then the stack is automatically unrolled as per documented C++ behaviour
        }
    private:
        QPushButton b; //< Can't get more throw-safe than this!
    };
    


  • OK, I understand your strategy; thanks for the advice.

    Steve.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.