Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Delete vs deleteLater()



  • Hi,
    for me it isn't clear if there is a difference using delete or the deleteLater() slot?

    void Class::create()
    {
       if (m_timer != nullptr) 
          delete m_timer ; // <-- or m_timer->deleteLater()  ?
         
       m_timer = new QTimer();
       connect(m_timer , &QTimer::timeout, this, &Class::process);
       connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); // delete the member when the class is going to be destroyed
    }
    

    Is there a advantage using deleteLater() in the if-clause?

    Thanks !



  • If you have an event loop and no real memory cluttering then the suggestion is to use deleteLater() so you don't have to worry. If you use delete directly you must make sure that:

    • There are no pending events that m_timer should receive (in this case a timerEvent) or it might crash
    • You must make sure m_timer lives in the same thread as the one you are calling delete from
    • You must make sure the method in which you call delete is not a slot triggerd by the object you are trying to delete or it might crash

    Basically, life is too short to care about all the above and the performance improvement is negligible so using deleteLater() is just better in this case

    P.S.
    connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); can be replaced by just passing this to the QTimer's constructor


  • Moderators

    @beecksche said in Delete vs deleteLater():

    Is there a advantage using deleteLater() in the if-clause?

    Depends on the use case.

    If you expect that the pointer still receives some event in the current event loop iteration, or shortly after the current execution and want to "mark it as deleted" you use deleteLater()
    Otherwise you can always call delete.

    Another example: if you want to delete a pointer, but still have to pass it to a base-class implementation to let this base class also finish its work you also must call deleteLater.

    But basically if you are unsure try it with delete, if you encounter issues, try deleteLater. If there are still issues there is a bug/misconception in the code.



  • Thanks for the replies and information. I will use the deleteLater() slot!

    @VRonin :

    P.S.
    connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); can be replaced by just passing this to the QTimer's constructor

    My class Class is moved to another thread and the create function is invoked (to create the members in thread1).

    ...
    class.moveToThread(&thread1);
    ...
    QMetaObject::invokeMethod(&class, "create", Qt::QueuedConnection);
    ...
    

    So if I would use

    m_timer = new QTimer(this);
    

    this (Class object) isn't be created in thread1. And so the parent (this) is not allowed to delete the QTimer object (because it "lives" not in the same thread). Or do I misunderstood this?



  • @beecksche said in Delete vs deleteLater():

    Or do I misunderstood this?

    if you move class to a second thread then Class::create should be called in the second thread and m_timer can be made child of class the problem is only if you give a parent that lives in another thread, this should not be the case.

    It's at least risky to have class on the stack and move it to the second thread as it might go out of scope and crash the thread that tries to use it.



  • @VRonin

    I followed the thread example in the documentation: http://doc.qt.io/qt-5/qthread.html



  • Which one? did you reimplement run()?

    As you can see Worker *worker = new Worker; which is the equivalent of your class is not on the stack and, although the example doesn't show it, Worker is free to have child objects



  • @VRonin

    The first one, I move the class to the thread!

    In my example I used the wrong operator ".". It should be "->"


Log in to reply