Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    How to deal with deleted slot object

    General and Desktop
    3
    6
    4585
    Loading More Posts
    • 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.
    • J
      justDance last edited by

      main thread has object A function member aa(). It is a slot function connecting to worker thread object B signal bb(). Now bb() is triggered by another object C signal cc() in worker thread, but main thread just deleted object A, I got first-class exception at QMetaObject::activate().

      Can't Qt gracefully handle this case if slot object is deleted, just do not trigger slot function??
      How can I fix this issue? seems Mutex can't fix my problem, because all those are signal slots rather than direct function calls so Mutex will just unlock once it is out of scope.

      1 Reply Last reply Reply Quote 0
      • J
        justDance last edited by

        I have another crash case, object A function member aaa(). It is callback function called by worker thread object B function bbb(). The callback is established by boost::bind() and boost::function().

        Now bbb() is triggered by another object C signal ccc() in worker thread, but main thread just deleted object A, bbb() will still call aaa(), at this moment I can see object A this pointer is not reinitialized, aaa() function pointer is not reinitialized but all its data members are reinitialized to 0xfeeefeee. so it crashes inside aaa() when using those data members.

        Although here it is a boost function pointer issue, I feel it is very similar to the issue I mentioned above.

        What's the good solution?

        Thanks,

        1 Reply Last reply Reply Quote 0
        • J
          justDance last edited by

          For the first issue, if I set object A pointer to NULL in destructor, Can Qt gracefully do not trigger slot function by detecting object A does not exist?

          1 Reply Last reply Reply Quote 0
          • Chris Kawa
            Chris Kawa Moderators last edited by

            When a QObject is destroyed all of the pending events are dropped and all connections are disconnected automatically so there's no problem there. Also look at the docs on the "QObject destructor":http://doc.qt.digia.com/qt/qobject.html#dtor.QObject, it might be just your case.

            It sounds more like you lost track of pointers validity across threads.
            The best thing to do would be to rethink and maybe simplfy your app execution flow.

            But if that is not an option you can take a look at a QPointer - it's a wrapper class around QObject pointers that automatically gets set to 0 when a pointed object is destoyed.

            1 Reply Last reply Reply Quote 0
            • J
              justDance last edited by

              Krzysztof Kawa, thank you very much. I got some hint from your post. In my case, object A and object B are highly related. class A has a class-B-type pointer as a data member. A's destructor will emit signal to inform worker thread to delete B. Note B has to be deleted in worker thread since it's created there.

              @ A::~A() {
              if(b_ptr != NULL) {
              emit DeleteB(b_ptr);
              b_ptr = NULL;
              }
              }@

                @  wokerThread::OnDeleteB(b) {
                        delete b;
                  }@
              

              Based on your post, I think I should not call "delete b" directly in wokerThread::OnDeleteB(). because it is possible that C's signal is already emitted and the pending event is waiting to be delivered.

              But how about my second crash case of boost::function? I can see boost is using object A pointer to call the callback function (as boost calls a_ptr->aaa()). In debugging build, that pointer is not reinitialized to 0xfeeefeee, but all its data members are reinitialized.

              1 Reply Last reply Reply Quote 0
              • O
                ogoffart last edited by

                It is hard to understand the problem, without more information.
                Keep in mind that:

                • An object should be destroyed in its own thread.
                • If you add your slots in a QThread, they will be executred in the parent thread, because the QThread object does not live in itself. Adding slots to a QThread is not recommended.
                • Qt alreay provide a slot to delete objects, it is the QObject::deleteLater slot. You can connect directly to that slot if you wish.
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post