Unable to hold QQmlContext in std::shared_ptr

0

I noticed some quite strange behavior when working with Qt 5.15/C++.

I was working on a small application when I wanted to set a context property for my root context.

My application is a QtQuick app which uses QQmlApplicationEngine instead of QQuickView (which was, for whatever reason, the default when creating a Qt Quick app):

QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));

// ...

QStringList entryList { "String1", "String2", "String3" };

Then, when assigning the string list as a context property for my root context, I wanted to use STL shared pointers instead of raw pointers:

std::shared_ptr<QQmlContext> context = std::make_shared<QQmlContext>(engine.rootContext());

if (!context) {
    qDebug() << "Failed to get root context. exiting.";
    exit(-1);
}

context->setContextProperty("entryList", QVariant::fromValue(entryList));

My entry list will be empty inside QML.

However, when I use raw pointers:

QQmlContext* context = engine.rootContext();

// ...

everything works just fine and the entryList var is filled inside QML.

Is there a logical behaviour behind this which I don't yet understand?

By the way, when using QSharedPointers instead of shared_ptr, The list will be filled, however I'm getting a debugger exception on exit:

Exception at 0x7ff8022f2933, code: 0xc0000005: read access violation at: 0xffffffffffffffff, flags=0x0 (first chance)

c++
qt
stl
qml
shared-ptr
asked on Stack Overflow May 19, 2021 by taiBsu

1 Answer

1

Qt clearly indicates when the developer must manage the memory of an object, if it does not indicate it then it must be assumed that Qt will eliminate it when necessary.

In this particular case the QQmlContext is created by QQmlApplicationEngine so it is the responsibility of that class to manage its memory. For example, a different case is QNetworkAccessManager is that in the docs it indicates that the developer must handle the memory of the created QNetworkReply(docs):

Note: After the request has finished, it is the responsibility of the user to delete the QNetworkReply object at an appropriate time. Do not directly delete it inside the slot connected to finished(). You can use the deleteLater() function.

The memory management that Qt is responsible for can be done through the QObject hierarchy or use its own pointers (QPointer, QSharedPointer, etc) but that is irrelevant for the developer since that is part of the private Qt API.

answered on Stack Overflow May 19, 2021 by eyllanesc • edited May 19, 2021 by eyllanesc

User contributions licensed under CC BY-SA 3.0