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

How do you keep a class from deleting an argument passed in by reference?



  • I ran into a problem while working with the Simple Browser example, I wanted to move the popup dialog for downloads, into a tab, so I passed the reference to the DownloadWidget defined at the parent level, by reference to the Tab Widget as context to the tab, but when closing the app, the TabWidget tries to delete the reference, but the owner of it already deleted it, so its an invalid pointer, and why it crashes, but I have no idea how to prevent this, I have spent a week trying to figure this out, I thought about writing a smaller demo, but found its the interaction between all the classes and the order they delete things in that causes this issue, and this is in fact a Qt Example that some people might be familiar with.

    I published this project on GitHub
    https://github.com/Light-Wizzard/QtWebBrowser
    The read me gives all the details and the code is there.

    Thanks, Flesh.



  • @Flesh

    Short answer: You can't (prevent the TabWidget from deleting its pages / childs)

    You add your widget to your tab with addTab(...). The ownership of your DownloadManagerWidget went to your QTabWidget and it will be cleaned when the tabWidget is also destroyed
    (-> QObject - Parent-Child-ObjectTree)

    If you delete your DownloadManagerWidget elsewhere, you will face some crashes and unwanted behavior (like you probably do, at the moment).

    Edit:

    Haven't seen all of your code... do you delete your widget manually in your BrowserWindow?
    It's risky to just pass pointers to widgets around and having them laying around.

    You might want to have a look at QSharedPointer
    (dunno whether it helps in your case. Maybe you have to re-organize your widgets)


  • Lifetime Qt Champion

    @Pl45m4 said in How do you keep a class from deleting an argument passed in by reference?:

    You might want to have a look at QSharedPointer

    Don't use QSharedPointer with QObjects!



  • @Christian-Ehrlicher

    Hm I thought it's possible.

    What about this example from the documentation?
    Isn't MyObject a QObject there?!

        QSharedPointer<MyObject> obj =
            QSharedPointer<MyObject>(new MyObject, &QObject::deleteLater);
    
    


  • That worked, thanks.



  • @Christian-Ehrlicher is right that you should avoid (in general at least) to use a shared pointer with QObject. Try to always use the parent to manage the lifetime of QObjects. Once you start mixing the two you might easily provoke a double free. Be aware that Qt also automatically sets parents in some cases! Whenever you place a widget into a layout it will be reparented. It is much easier to avoid shared pointers with QObject than to try to figure out all the corner cases.


Log in to reply