2017-07-29 156 views
0

上节目结束这个简单的代码崩溃(Qt的5.9.1,5.4.1 GCC):shared_ptr的<QCoreApplication>崩溃

#include <QCoreApplication> 
#include <memory> 

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

我知道通常的方法是在堆栈上声明一个QCoreApplication实例并在main()结束时销毁它,但我的用例如下所示:我正在用Boost.Python封装一个使用Qt的库,并且在python模块加载时我像上面那样初始化Qt。但是,除非强制用户拨打finalize()方法,否则我无法销毁QCoreApplication

想法是当库(python模块)被卸载时被破坏,但这似乎不起作用。上述预期,如果是这样,为什么? “破坏秩序问题”是我的第一个猜测,但在这种情况下,这应该被视为一个错误?

+0

应用程序对象是一个全局变量/单例(你可以使用'qApp'或'QCoreApplication :: instance()'来获得它,初始化可能会做很多事情,我不确定你是否真的卸载它。最好从Python创建应用程序实例,然后使用它。 –

回答

2

问题(正如Lukas在他上面的评论中指出的那样)是共享指针是一个全局对象,这意味着在进程退出时,它的析构函数将不会在main()返回之后被调用,点(我猜测但非常有信心)QCoreApplication对象的析构函数可能访问的各种数据结构已经被拆除并处理掉了,所以当它尝试访问它们时会发生崩溃。 (例如,你传递给QCoreApplication构造函数的argv指针可能不再有效时,该QCoreApplication析构函数运行时间)

不过,我也没有办法摧毁QCoreApplication除非我强迫 用户调用一些finalize()方法。

你可以尝试的一件事是注册一个回调函数atexit()删除QCoreApplication对象。希望atexit()回调将在关闭序列中足够早地调用,这将使您获得所需的行为。 (或者如果一切都失败了,你可以让QCoreApplication对象泄漏;因为这个过程即将被销毁,我认为这样做不会特别有害)

+0

非常明确的解释,谢谢。从您链接的页面:_ [...]可用于建立共享库卸载时调用的函数。虽然这似乎适用于我的问题的基本示例,但它不对于python绑定的完整案例。我读[这里](https://stackoverflow.com/a/13586487/1229582),应该定义调用序列,但我认为(从C++ 11开始)[this](http://en.cppreference .com/w/cpp/utility/program/atexit)适用:_函数可以与静态存储持续时间同时销毁对象一起调用..._ – matpen

+0

经过更多测试,我找不到比'QCoreApplication'漏洞更好的解决方案。目的。接受答案,因为它提供了一个非常合理的解释。 – matpen