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] Destructor called twice and causes app crash
QtWS25 Last Chance

[solved] Destructor called twice and causes app crash

Scheduled Pinned Locked Moved General and Desktop
10 Posts 2 Posters 6.8k 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.
  • K Offline
    K Offline
    kermal369
    wrote on 22 Jul 2014, 09:11 last edited by
    #1

    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
    0
    • S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 22 Jul 2014, 09:40 last edited by
      #2

      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
      0
      • K Offline
        K Offline
        kermal369
        wrote on 22 Jul 2014, 10:21 last edited by
        #3

        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
        0
        • S Offline
          S Offline
          sierdzio
          Moderators
          wrote on 22 Jul 2014, 10:25 last edited by
          #4

          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
          0
          • K Offline
            K Offline
            kermal369
            wrote on 22 Jul 2014, 10:49 last edited by
            #5

            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
            0
            • S Offline
              S Offline
              sierdzio
              Moderators
              wrote on 22 Jul 2014, 10:54 last edited by
              #6

              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
              0
              • K Offline
                K Offline
                kermal369
                wrote on 22 Jul 2014, 11:07 last edited by
                #7

                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
                0
                • S Offline
                  S Offline
                  sierdzio
                  Moderators
                  wrote on 22 Jul 2014, 11:12 last edited by
                  #8

                  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
                  0
                  • K Offline
                    K Offline
                    kermal369
                    wrote on 22 Jul 2014, 11:25 last edited by
                    #9

                    Ok, thank you, sierdzio
                    Solved.

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      sierdzio
                      Moderators
                      wrote on 22 Jul 2014, 11:38 last edited by
                      #10

                      You are welcome, happy coding :-)

                      (Z(:^

                      1 Reply Last reply
                      0

                      1/10

                      22 Jul 2014, 09:11

                      • Login

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