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. signal/slot arguments

signal/slot arguments

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 1.6k Views
  • 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by mzimmers
    #1

    Hi all -

    Is this dangerous?

    MyClass myObj = new MyClass;
    emit mySignal(myObj);
    delete myObj;
    

    And if it is, what's the recommended method of obviating this?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      It depends how you have connected the mySignal.
      If within same thread, the emit should be like a function call and
      it should not crash.

      However, if between threads ( Qt::QueuedConnection ) and and Qt saves the pointer and deliver the signal via event loop, it would not be good.

      But im wondering why cant the reciever just create a Myclass and use.
      Since you delete at once, you seem not to need it where emit is called?

      1 Reply Last reply
      3
      • mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by mzimmers
        #3

        Oh, in my example, I neglected to include the step that populated myObj:

        MyClass *myObj = new MyClass;
        myObj.myElement = myValue;
        emit mySignal(myObj);
        delete myObj;
        

        EDIT: fixed mistake in code example.

        Basically, I was curious whether the signal/slot mechanism had some built-in protection against a race condition that this code would cause. I think you answered that: if within a thread, it's OK; if not, it's unsafe. Thanks...

        mrjjM W 2 Replies Last reply
        0
        • mzimmersM mzimmers

          Oh, in my example, I neglected to include the step that populated myObj:

          MyClass *myObj = new MyClass;
          myObj.myElement = myValue;
          emit mySignal(myObj);
          delete myObj;
          

          EDIT: fixed mistake in code example.

          Basically, I was curious whether the signal/slot mechanism had some built-in protection against a race condition that this code would cause. I think you answered that: if within a thread, it's OK; if not, it's unsafe. Thanks...

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @mzimmers
          Within SAME thread. (like main GUI thread)
          then the argument is not stored nothing bad can happen.
          Alternatively, you could just send by copy if MyClass is fine with that.
          ( as in has no char * or anything that would not copy ok)

          MyClass myObj;
          myObj.myElement = myValue;
          emit mySignal(myObj); // would copy
          You could change the signal to
          void mySignal( MyClass & obj)
          and it would transfer as reference. Much like pointer but
          no need to delete it. ( scope will delete it)

          1 Reply Last reply
          1
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #5

            Yes, that makes sense. Since my example is indeed across threads, though, I have to deal with the potential problem you mentioned.

            I think for my purposes, using Qt::BlockingQueuedConnection will work. Either that, or something like slot signaling back an acknowledgement when it's finished, so the sender can then delete the object, but...that sounds like more trouble than it's worth for this application.

            1 Reply Last reply
            0
            • mzimmersM mzimmers

              Oh, in my example, I neglected to include the step that populated myObj:

              MyClass *myObj = new MyClass;
              myObj.myElement = myValue;
              emit mySignal(myObj);
              delete myObj;
              

              EDIT: fixed mistake in code example.

              Basically, I was curious whether the signal/slot mechanism had some built-in protection against a race condition that this code would cause. I think you answered that: if within a thread, it's OK; if not, it's unsafe. Thanks...

              W Offline
              W Offline
              wrosecrans
              wrote on last edited by
              #6

              @mzimmers said in signal/slot arguments:

              I think you answered that: if within a thread, it's OK

              This only applies if you haven't got any queued connections set up. The default behavior of connect is to use queued connections when it sees that two objects are owned by different threads, but it's entirely possible to set up queued connections in other circumstances. In that case, the slot won't trigger until after the object has been deleted, regardless of threading.

              Also, if the slot does anything to retain the pointer somewhere rather than just doing some immediate work, obviously that will explode. If possible, avoid sending raw pointers like this, if there's any ambiguity about lifetime and ownership.

              You can also look into QObject's delete later : http://doc.qt.io/qt-5/qobject.html#deleteLater

              That asks the event loop to delete an object at some point in the future, which is useful if you want it to get deleted after the event loop is done doing some activity with it.

              mzimmersM 1 Reply Last reply
              3
              • mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @mzimmers
                Oh, if between threads, care must be taken.
                I normally make sure the class is copyable if not too expensive and
                register it to the metasystem so it can cache it.
                http://doc.qt.io/qt-5/custom-types.html
                As @wrosecrans says, sending pointers is not optimal and add the lifespan and deletion issues. Smart pointers can help but
                the best solution really depends on what MyClass contains of data.
                BlockingQueuedConnection should work though but i never tested that.

                1 Reply Last reply
                0
                • W wrosecrans

                  @mzimmers said in signal/slot arguments:

                  I think you answered that: if within a thread, it's OK

                  This only applies if you haven't got any queued connections set up. The default behavior of connect is to use queued connections when it sees that two objects are owned by different threads, but it's entirely possible to set up queued connections in other circumstances. In that case, the slot won't trigger until after the object has been deleted, regardless of threading.

                  Also, if the slot does anything to retain the pointer somewhere rather than just doing some immediate work, obviously that will explode. If possible, avoid sending raw pointers like this, if there's any ambiguity about lifetime and ownership.

                  You can also look into QObject's delete later : http://doc.qt.io/qt-5/qobject.html#deleteLater

                  That asks the event loop to delete an object at some point in the future, which is useful if you want it to get deleted after the event loop is done doing some activity with it.

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #8

                  Thanks to both of you for the explanation. I'll avoid passing pointers as arguments in signal/slot calls.

                  mrjjM 1 Reply Last reply
                  0
                  • mzimmersM mzimmers

                    Thanks to both of you for the explanation. I'll avoid passing pointers as arguments in signal/slot calls.

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @mzimmers
                    Its not a no go in all cases like when you have a member object in mainwindow and you are sure its life spans matches the application
                    and you only signal it out for short processing and the pointer is not stored in the using classes. Also sometimes the object creation is so expensive you must use a pointer to avoid copying etc.

                    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