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. [SOLVED] self-deleting objects
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] self-deleting objects

Scheduled Pinned Locked Moved General and Desktop
13 Posts 7 Posters 7.3k Views 1 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.
  • P Offline
    P Offline
    planarian
    wrote on 20 Sept 2012, 14:12 last edited by
    #1

    Let's say I have an object, A, which emits a signal. Object B's slot responds by calling a method of C, which deletes A. The problem (at least in my program) is that A is still on the stack, so this results in a segmentation fault. The way I imagine solving this is to have C run in its own thread and execute with a delay, giving A time to complete. Are there better alternatives? I don't have any experience with threads.

    Thanks!

    [edit: changed the scenario slightly]

    1 Reply Last reply
    0
    • K Offline
      K Offline
      KA51O
      wrote on 20 Sept 2012, 14:14 last edited by
      #2

      You could use deleteLater() instead of delete if A and B are derived from QObject.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on 20 Sept 2012, 14:42 last edited by
        #3

        Congratiolations, you have stumbled on the dangers of emitting signals: you give away control over the application to <deighty> knows where in your application, at which point anything can happen, including the deletion or otherwise any manipulation of the emitting object. :-)

        There are tricks to guard against this happening, but they are not all simple. Some basic pointers:

        If possible at all, do the signal emission last in the method that emits them. That prevents some problems.

        Edit: Considder if your signal should not be emitted asynchronously, so after returning to the eventloop even if you trigger it mid-code in your emitting object.

        If you have to have an emit in the middle of your code, try to:

        Make sure that your object is in a consistent state when you do, and

        Assure your application will not break if other methods on the object are called at that point, and

        Check that your object is still alive after the emit took place!

        A trick to check if your object is still alive (last point above), is to have a QPointer<TheClass>(this) variable as a guard in the method where you do the emit. You can then check if this variable was nulled after the emit. If it was, return immediately.

        So:
        @
        void MyClass::someMethod()
        {
        QPointer<MyClass> guard(this);

        //work
        
        //emit something, perhaps progress
        emit someSignal(value);
        
        //check if we're still alive!
        if (!guard)
           return; //exit if we are not
        
        //more work
        return;
        

        }
        @

        There are more advanced tricks that you might employ, but these are some basics.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sierdzio
          Moderators
          wrote on 20 Sept 2012, 15:58 last edited by
          #4

          This is pure gold, Andre :) Very nice trick.

          (Z(:^

          1 Reply Last reply
          0
          • P Offline
            P Offline
            planarian
            wrote on 20 Sept 2012, 16:54 last edited by
            #5

            @Andre: I've changed the scenario in my original post slightly to more accurately reflect my setup: A signals B, B calls method of C, C deletes A, causing a seg fault. The timing of the deletion is important because C then reconstructs A with new parameters. A's signal does appear as its last instruction, but Qt Creator's debugger seems to indicate that A never gets a chance to exit before B's slot fully executes. That's why I was wondering whether I need another thread.

            @KA510: I tried deleteLater(). The problem, as mentioned above, is that the deletion needs to be accompanied by a reconstruction of the object, and I don't see any way to schedule them together.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on 20 Sept 2012, 17:09 last edited by
              #6

              Sorry, but no, I do not see that sequence working like this.

              What you could try, is connect the signal from A to B as a queued signal/slot connection. That way, A will have time to exit the procecure where the signal is emitted in a controlled way. Only when control returns to the eventloop, the signal will be delivered, and you can savely delete A.

              1 Reply Last reply
              0
              • P Offline
                P Offline
                planarian
                wrote on 20 Sept 2012, 17:23 last edited by
                #7

                Does a "queued signal/slot connection" involve QThread? I'm looking around the site, and I'm not sure where to begin on this topic....

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mlong
                  wrote on 20 Sept 2012, 17:28 last edited by
                  #8

                  While queued connections ARE used between QThreads, they can be used independently for connections within a single thread. Adding a Qt::ConnectionType parameter to your connect() call to use a Qt::QueuedConnection just instructs the signal/slot system to push the call to your slot onto a queue, where the event loop will pick it up and execute it on the next event loop iteration. This is in contrast to the slot being called directly. Check the "QObject::connect()":/doc/qt-4.8/qobject.html#connect documentation for more details.

                  Software Engineer
                  My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    goblincoding
                    wrote on 20 Sept 2012, 17:30 last edited by
                    #9

                    Thanks for sharing a very interesting scenario and thanks Andre for a very cool tip :)

                    http://www.goblincoding.com

                    1 Reply Last reply
                    0
                    • P Offline
                      P Offline
                      planarian
                      wrote on 20 Sept 2012, 18:10 last edited by
                      #10

                      Adding Qt::QueuedConnection to the connect calls fixed it. Thanks very much, everyone!

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on 20 Sept 2012, 19:23 last edited by
                        #11

                        [quote author="planarian" date="1348164616"]Adding Qt::QueuedConnection to the connect calls fixed it. Thanks very much, everyone![/quote]

                        Note that the advice I gave still goes: as your class has no control over how it is connected to other components (directly or via a queued connection), it is a good idea to be careful about what happens when emitting a signal.

                        Still, I am happy to hear that using a queued connection solved your problem.

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          Sam
                          wrote on 21 Sept 2012, 14:03 last edited by
                          #12

                          Bravo!!! That a cool trick !!! thanks Andre

                          I wish we could also dockmark these posts/topics like other pages. Or May be we can add a page to Wiki.

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on 21 Sept 2012, 14:12 last edited by
                            #13

                            [quote author="Sam" date="1348236234"]Bravo!!! That a cool trick !!! thanks Andre

                            I wish we could also dockmark these posts/topics like other pages. Or May be we can add a page to Wiki.

                            [/quote]
                            Thanks :-)

                            To give credit where credit is due: I had quite a bit of inspiration from "this":http://delta.affinix.com/dor/ page.

                            1 Reply Last reply
                            0

                            1/13

                            20 Sept 2012, 14:12

                            • Login

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