静态 QApplication 变量 Mac 报告退出时崩溃
Static QApplication variable made Mac reports an crash on exit
以下代码 运行 在 Windows 或 Linux (Debian) 上运行良好,但在 Mac 上报告退出时崩溃:
int main(int argc, char *argv[]) {
static QApplication app(argc, argv);
QPushButton w; w.show();
return app.exec();
}
我需要这个应用变量必须是静态的。
我通过以下方式解决此问题:
static QApplication& app = *new QApplication(argc, argv);
但是我不喜欢这种风格。你有什么建议吗?
非常感谢!
更新:添加关于报告的图像(并更新我正在使用的代码示例):
不要将 QApplication app
定义为 static
。
您可以在代码的任何地方使用 qApp
or QCoreApplication::instance()
。
示例:
QString appDir = qApp->applicationDirPath();
与
相同
QString appDir = QCoreApplication::instance()->applicationDirPath();
您关于它 "works" 的断言充其量只是隐喻。您没有提到崩溃发生在退出时。这是一个非常重要的细节。
崩溃的原因是你失去了对破坏顺序的控制。静态存储持续时间的值,例如您示例中的 QApplication
,在 main()
退出后的某个时间被 C++ 运行时破坏。
Qt 在内部出于各种目的使用静态变量。恰好当QApplication::~QApplication
析构函数运行时,这些变量的值已经被析构了。崩溃发生在 qt_call_post_routines()
中,在 cleanupDevicesList()
post 例程中。它试图访问死对象。
它在 Windows 和 Linux 上 "works" 的原因与它在 Mac 上 "doesn't work" 的原因相同:您面临未定义的行为.未定义的行为仅仅意味着它既不能保证工作,也不能保证失败。你碰巧看到两种极端行为。问题的症结在于您不应该编写调用未定义行为的代码。今天 Windows "works" 为您提供,但在重要的客户演示期间可能无法使用。
以下代码 运行 在 Windows 或 Linux (Debian) 上运行良好,但在 Mac 上报告退出时崩溃:
int main(int argc, char *argv[]) {
static QApplication app(argc, argv);
QPushButton w; w.show();
return app.exec();
}
我需要这个应用变量必须是静态的。 我通过以下方式解决此问题:
static QApplication& app = *new QApplication(argc, argv);
但是我不喜欢这种风格。你有什么建议吗? 非常感谢!
更新:添加关于报告的图像(并更新我正在使用的代码示例):
不要将 QApplication app
定义为 static
。
您可以在代码的任何地方使用 qApp
or QCoreApplication::instance()
。
示例:
QString appDir = qApp->applicationDirPath();
与
相同QString appDir = QCoreApplication::instance()->applicationDirPath();
您关于它 "works" 的断言充其量只是隐喻。您没有提到崩溃发生在退出时。这是一个非常重要的细节。
崩溃的原因是你失去了对破坏顺序的控制。静态存储持续时间的值,例如您示例中的 QApplication
,在 main()
退出后的某个时间被 C++ 运行时破坏。
Qt 在内部出于各种目的使用静态变量。恰好当QApplication::~QApplication
析构函数运行时,这些变量的值已经被析构了。崩溃发生在 qt_call_post_routines()
中,在 cleanupDevicesList()
post 例程中。它试图访问死对象。
它在 Windows 和 Linux 上 "works" 的原因与它在 Mac 上 "doesn't work" 的原因相同:您面临未定义的行为.未定义的行为仅仅意味着它既不能保证工作,也不能保证失败。你碰巧看到两种极端行为。问题的症结在于您不应该编写调用未定义行为的代码。今天 Windows "works" 为您提供,但在重要的客户演示期间可能无法使用。