matpen
matpen

Reputation: 291

shared_ptr<QCoreApplication> crashes

This simple code crashes on program end (Qt 5.9.1, gcc 5.4.1):

#include <QCoreApplication>
#include <memory>

std::shared_ptr<QCoreApplication> manager;
int main(int argc, char *argv[])
{
    manager = std::make_shared<QCoreApplication>(argc, argv);
}

I know that the usual way is to declare a QCoreApplication instance on the stack, and have it destroyed at the end of main(), but my use case is as follows: I am wrapping a library that makes use of Qt with Boost.Python, and I initialize Qt like above when the python module gets loaded. However, I have no way to destroy the QCoreApplication unless I force the user to call some finalize() method.

The idea was then to have it destroyed when the library (python module) gets unloaded, but this does not seem to work. Is the above expected, and if so, why? "Destruction order problem" is my first guess, but in this case, should this be regarded as a bug?

Upvotes: 1

Views: 271

Answers (1)

Jeremy Friesner
Jeremy Friesner

Reputation: 73304

The problem (as Lukas pointed out in his comment above) is that the shared pointer is a global object, which means that on process exit, its destructor won't be called until after main() has returned, at which point (I'm speculating but pretty confident) various data structures that the QCoreApplication object's destructor might access have already been torn down and disposed of, and so you get a crash when it tries to access them. (For example, the argv pointer that you pass to the QCoreApplication constructor might not be valid anymore at the time that the QCoreApplication destructor runs)

However, I have no way to destroy the QCoreApplication unless I force the user to call some finalize() method.

One thing you could try is to register a callback function with atexit() that deletes the QCoreApplication object. Hopefully the atexit() callback will get called early enough in the shutdown sequence that this would get you the behavior you want. (Or if all else fails you could just let the QCoreApplication object leak; since the process is about to be destroyed anyway I don't think that would be particularly harmful to do)

Upvotes: 3

Related Questions