0

I have a class, that inherits QAbstractListModel. It's instance (which created with dynamically with new operator) registered in qml with setContextProperty(). In Qml it uses with GridLayout and Repeater.

Problem arises, when i closed my program: i do it from qml with following code:

    quitButton{
        onClicked: {
            application.close();
            Qt.quit()
        }
    }

And the program crashes on

delete(instanceOfModelClass);

with access violation. I tried set QObject's parent for this instancies, set QQmlEngine::CppOwnership for this objects in engine, but it still doesn't work.

How i can fix that problem?

P.S. If i erased delete(instanceOfModelClass); line it will work, but, as i understood, there will be meamory leak.

Nikxp
  • 355
  • 3
  • 13
  • Either setting a parent or `CppOwnership` should work. It would help if you could provide a minimal, complete example that demonstrates the issue. Alternatively, you could just create `instanceOfModelClass` on the stack instead (assuming you're creating it in `main()`). – Mitch Oct 26 '17 at 10:30
  • When you create the model, do you set a parent, that might be deleted before? – derM - not here for BOT dreams Oct 26 '17 at 10:37
  • **Regarding your PS**: That is platform dependent. See https://stackoverflow.com/questions/2975831/is-leaked-memory-freed-up-when-the-program-exits - on many systems you won't have problems, but I would consider it good style to clean up. Who knows on what platform the next guy is going to run your code. – derM - not here for BOT dreams Oct 26 '17 at 11:07
  • For Qt applications and QObject-derived objects, I usually set a parent - if no better available, I use the `QGuiApplication` which I allocate on the stack. This helps with cleaning up, as when a object gets destroyed, all children are going to die first. – derM - not here for BOT dreams Oct 26 '17 at 11:11
  • Yes, the problem was in incorrect delete order before it's children. When i set parent to all elements, and delet's them in correct sequence, it's don't crash anymore. I learned a bit more about Qt's ownership. Thanks. – Nikxp Oct 28 '17 at 11:58

2 Answers2

0

Problem was solved, when QObjects parents were set. And deleting calls in right order.

Nikxp
  • 355
  • 3
  • 13
-1

I think that your program crash because the pointer has been previously removed in other place. Try to check if the pointer still exist before removing it, you can do something like that:

if (myPointer != nullptr) delete myPointer;

Another alternative is to use QScopedPointer that will remove the pointer automatically when it goes out of the scope. I suppose that you create your pointer in the main function, so something like that:

QScopedPointer<MyClass> scp(new MyClass()); // no need to set a parent
MyClass* myClassPtr = scp.data(); // use this one to pass it to the qml context.
mohabouje
  • 3,867
  • 2
  • 14
  • 28
  • Doesn't this require, that you set a deleted pointer to `nullptr`? – derM - not here for BOT dreams Oct 26 '17 at 11:15
  • I don't understand, I just check if the pointer still alive to remove it. Where I'm setting it to nullptr? – mohabouje Oct 26 '17 at 12:37
  • After you delete it, so the next time you are not sure, whether to delete the pointer *you can actually check whether it is still alive*. After calling `delete myPointer` it is not necessary that `myPointer == nullptr` - **afaik** – derM - not here for BOT dreams Oct 26 '17 at 12:41
  • Maybe I'm not right but for QObject, compare with Q_NULLPTR is the correct way to check if the pointer is null, and normally is NULL or nullptr depends of the version of C++ – mohabouje Oct 26 '17 at 13:11
  • 1
    `Q_NULLPTR` is only a macro that expands to `nullptr` if the C++ version supports that. But if you have `MyClass* m = new MyClass(); if (m != nullptr) delete m; if (m != nullptr) delete m;` it might crash as the second time you have `if (m != nullptr)` m is not necessary a `nullptr`. So if you can't be sure that you delete it only once, you should write `MyClass* m = new MyClass(); if (m != nullptr) { delete m; m = nullptr } if (m != nullptr) { delete m; m = nullptr; };` - **afaik** - or, as you can safely delete a `nullptr` you can omit the check. – derM - not here for BOT dreams Oct 26 '17 at 13:23
  • Ok, I got it! Thanks! – mohabouje Oct 26 '17 at 13:50