Umgang von QML mit C++ Pointern
In der Qt-Dokumentation über QML gibt es einen interessanten Abschnitt Data Ownership der sollte in dem Fall beherzigt werden, ansonsten läuft man Gefahr sich ein Memory-Leak zu programmieren.
Was steht dort eigentlich genau beschrieben?
Wenn Daten von C++ nach QML transferiert werden. Dann liegt der Besitz der Daten in C++-Hand. Das wäre zum Beispiel der Fall bei einer Q_PROPERTY.
Q_PROPERTY(int* test READ getTest)
Das heißt, die Daten werden im C++-Code verwaltet und der Speicher muss von dort aus auch verwaltet werden. Alles ist also in Ordnung wenn man sich darum im C++-Code kümmert.
Wenn Allerdings statt einer Q_PROPERTY ein Q_INVOKABLE verwendet wird, kümmert sich QML um die Speicherverwaltung.
Q_INVOKABLE int* getTest();
Diese Funktion liefert an QML einen Pointer auf einen Integer, QML wird den Speicher automatisch wieder freigeben, wenn der Pointer nicht mehr benötigt wird. Wird die Variable im C++-Abschnitt dennoch verwendet führt das zu einem Segmentation Fault. Will man die Ownership wieder in C++ haben gibt es die Möglichkeiten über die Funktionen QQmlEngine::setObjectOwnership() mit QQmlEngine::CppOwnership zu gehen. Möchte man auch bei Q_INVOKABLE grundsätzlich die Ownership behalten, gibt es die Möglichkeit sofern das zurückgegebene Objekt ein Q_OBJECT ist einen Parent-Pointer zu setzen, dieser verhindert das QML das Objekt löscht.