shared_ptr<QCoreApplication> 崩溃
Posted
技术标签:
【中文标题】shared_ptr<QCoreApplication> 崩溃【英文标题】:shared_ptr<QCoreApplication> crashes 【发布时间】:2017-07-29 20:26:43 【问题描述】:这个简单的代码在程序结束时崩溃(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);
我知道通常的方法是在堆栈上声明一个QCoreApplication
实例,并在main()
的末尾将其销毁,但我的用例如下:我正在包装一个使用的库Qt 与 Boost.Python,当 python 模块被加载时,我像上面一样初始化 Qt。但是,我无法销毁QCoreApplication
,除非我强制用户调用一些finalize()
方法。
当时的想法是在库(python 模块)被卸载时将其销毁,但这似乎不起作用。以上是预期的,如果是,为什么? “破坏顺序问题”是我的第一个猜测,但在这种情况下,这是否应该被视为一个错误?
【问题讨论】:
应用程序对象是一个全局变量/单例(您可以使用qApp
或QCoreApplication::instance()
获取它)并且初始化可能会做很多事情,我不确定您是否真的卸载它。最好从 Python 创建应用实例,然后直接使用它。
【参考方案1】:
问题(正如 Lukas 在上面的评论中指出的那样)是共享指针是一个全局对象,这意味着在进程退出时,直到 main() 返回之后才会调用它的析构函数,此时(我在推测,但非常有信心) QCoreApplication 对象的析构函数可能访问的各种数据结构已经被拆除和处置,因此当它尝试访问它们时会发生崩溃。 (例如,您传递给 QCoreApplication 构造函数的 argv 指针在 QCoreApplication 析构函数运行时可能不再有效)
但是,除非我强制,否则我无法销毁 QCoreApplication 用户调用一些 finalize() 方法。
您可以尝试的一件事是使用atexit() 注册一个回调函数,以删除 QCoreApplication 对象。希望 atexit() 回调将在关闭序列中尽早被调用,这将使您获得所需的行为。 (或者如果所有其他方法都失败了,您可以让 QCoreApplication 对象泄漏;因为无论如何该进程即将被销毁,我认为这样做不会特别有害)
【讨论】:
解释得很清楚,谢谢。从您链接的页面中:[...] 可用于 [...] 建立在卸载共享库时调用的函数。 虽然这似乎适用于我的基本示例问题,它不适用于 python 绑定的完整案例。我读到 here 应该定义调用顺序,但我认为(从 C++11 开始)this 适用:这些函数可以在销毁具有静态存储持续时间的对象的同时被调用。 . 经过更多测试,我找不到比泄漏QCoreApplication
对象更好的解决方案。接受答案,因为它提供了一个非常合理的解释。以上是关于shared_ptr<QCoreApplication> 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法将 shared_ptr<void> 转换为 shared_ptr<T>?
shared_ptr<QCoreApplication> 崩溃