Qt Forum

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

    Update: Forum Guidelines & Code of Conduct

    [solved] Destructor called twice and causes app crash

    General and Desktop
    2
    10
    5658
    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.
    • K
      kermal369 last edited by

      Problem: Passing variable to emit signal which is of simple class (not QObject). This class has destructor which deletes allocated pointers - as I understood this is mandatory for non QObject class - right?

      However inside of handling function on_bnScanStop_clicked() this destructor is called twice for some reason. (Or one more constructor missing?) . This causes app to crash when trying to delete non existing variable.

      Any clue how to deal with this?
      @
      "cfiledat00.h"
      class CFileDat00
      { public:
      CFileDat00();
      ~CFileDat00();
      CARMVrefItem *armvref;
      }

      "cfiledat00.cpp"
      CFileDat00::CFileDat00()
      {
      qDebug() << "CFileDat00 contructor";
      armvref = new CARMVrefItem(12,34,56);
      }
      CFileDat00::~CFileDat00()
      {
      qDebug() << "CFileDat00 destructor";
      delete armvref;
      }

      "mainwindow.cpp"
      void MainWindow::on_bnScanStop_clicked()
      {
      qDebug() << "on_bnScanStop_clicked enter";
      CFileDat00 filtmp;
      filtmp.scango->setHexval(0);
      emit sig_writef00(filtmp);
      qDebug() << "on_bnScanStop_clicked exit";
      }
      @
      The debug output of this code:
      @
      on_bnScanStop_clicked enter
      CFileDat00 contructor
      CFileDat00 destructor
      on_bnScanStop_clicked exit
      CFileDat00 destructor
      @

      Edit by sierdzio: added code tags

      1 Reply Last reply Reply Quote 0
      • sierdzio
        sierdzio Moderators last edited by

        Is this signal connected to a thread, or does it use Qt::QueuedConnection?

        The signal emission most probably creates a copy of the object (using default copy constructor - so pointers in both object point to the same thing!), so the destructor is called twice, once for your filtmp and second time for the copy.

        (Z(:^

        1 Reply Last reply Reply Quote 0
        • K
          kermal369 last edited by

          Up to this point signal is not connected to anywhere. It was initial intention to have filtmp copy in the signal. This is why I passed the object itself and not a pointer. I was expecting to see one more constructor - of a copy. But looking more broadly - why and how can destructor be called if constructor has never been called?

          1 Reply Last reply Reply Quote 0
          • sierdzio
            sierdzio Moderators last edited by

            Implicit copy constructor was called: this is the constructor that is created automatically by your compiler. It does not contain your debug statement for obvious reasons. To avoid it's creation, you can use "Q_DISABLE_COPY":http://qt-project.org/doc/qt-5/qobject.html#Q_DISABLE_COPY

            Or you can explicitly create your own copy constructor and handle the situation there. There are, of course, other options available, too: you can stop deleting the pointer in the destructor. Or you can change that CARMVrefItem into a stacked variable.

            (Z(:^

            1 Reply Last reply Reply Quote 0
            • K
              kermal369 last edited by

              ok, that explains things a bit why second constructor is not seen on debug. But why then this second destructor tries to kill the original filtmp and not its copy which was created by compiler Implicitly.
              Now it looks like both filtmp and its implicit copy inside signal has same pointer what in turn appears to be same object and not copy?

              1 Reply Last reply Reply Quote 0
              • sierdzio
                sierdzio Moderators last edited by

                To understand that, we need some background on pointers. When you define a pointer member in your class, all that is actually stored there is a (usually) 32 bit integer value that points to the real object in memory. That is why you can do something like this:
                @
                SomeClass *pointer = 0;
                // ...

                if (pointer) {
                // ...
                }
                @

                So, when the default copy constructor encounters a pointer, it will copy that number. It will not attempt to create a copy of the object that the pointer refers to.

                Then, when your destructor calls delete it no longer works on that number; it goes directly to the object in question, and calls it's destructor. The other object (the one you emit) attempts to do exactly the same thing, but the object it attempts to delete from memory is no longer there.

                (Z(:^

                1 Reply Last reply Reply Quote 0
                • K
                  kermal369 last edited by

                  bq. when the default copy constructor encounters a pointer, it will copy that number. It will not attempt to create a copy of the object that the pointer refers tobq.

                  This almost explain everything. Now remains question how to force compiler to create true copy of that object not just another set of pointers? In other words how to make it call real constructor?

                  1 Reply Last reply Reply Quote 0
                  • sierdzio
                    sierdzio Moderators last edited by

                    You've got 2 options here:

                    create your own copy constructor where you do all the things you want to

                    create your member variables on a stack, not on heap (that is: don't use pointers)

                    (Z(:^

                    1 Reply Last reply Reply Quote 0
                    • K
                      kermal369 last edited by

                      Ok, thank you, sierdzio
                      Solved.

                      1 Reply Last reply Reply Quote 0
                      • sierdzio
                        sierdzio Moderators last edited by

                        You are welcome, happy coding :-)

                        (Z(:^

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post