【问题标题】:After initializing class member app crashes with SIGSEGV [duplicate]使用 SIGSEGV 初始化类成员应用程序崩溃后 [重复]
【发布时间】:2016-10-05 14:35:12
【问题描述】:

我有带有 Application 类的 Qt 应用程序:

class Application : public QApplication {
public:
    Application(int argc, char** argv);
    ~Application();
};

在我添加之前一切正常

private:
    const QString NAME = "QtImageViewer";

当我尝试运行该应用程序时,它崩溃了 10 次中的 9 次


主要看起来像

int main(int argc, char** argv)
{
    Application app(argc, argv);
    app.setApplicationName("QtImageViewer");

    MainWindow mainWindow;
    mainWindow.show();

    return (app.exec());
}


我想知道怎么回事,因为我不知道。

编辑: GDB backtrace Valgrind

【问题讨论】:

  • 必须是别的东西。您添加的行应该可以正常工作。
  • @Jean-FrançoisFabre 是的,这就是我告诉自己的,没有那条线,一切正常,即使我运行调试,断点(sigsegv)在 app.exec()这是在我的程序逻辑之后
  • 如果你的应用程序的代码不是太大,也许可以发布它。
  • 我有根据的猜测:在您未显示的代码中的某处,有一个堆损坏错误。它曾经被忽视,但现在您已经有效地向 ~Application 添加了一个堆释放(NAME 正在被销毁),这恰好命中了堆的损坏区域。

标签: c++ qt segmentation-fault


【解决方案1】:

修复了,和here一样的问题。

我的 Application 类构造函数签名是 Application(int argc, char** argv); 但 QApplication 有 QApplication(int &argc, char **argv)

Application(int argc, char** argv); 更改为Application(int& argc, char** argv);,一切正常。

感谢大家的帮助。

【讨论】:

  • 我想到的附加信息,将来可能对您有所帮助。 Qt 本身没有问题,但是对于您使用的所有库,它们也提供了传递或请求 std 库的对象的可能性,您始终需要注意您使用的所有库都链接到相同(或二进制兼容)std库作为您的应用程序。尤其是在 Windows 下,如果 Qt 是为不同的 VisualStudio 版本构建的,那么这将是一个问题,然后您将其用于您的应用程序。在 linux 下这不是一个问题,因为您通常在包管理器上进行中继。
【解决方案2】:

我会发表评论,但在撰写本文时我还没有足够的声誉。作为记录,我克隆了您链接到的存储库。我注意到您似乎没有使用 Qt Creator,但可能只是在使用 cmake。我的 Qt 5 安装不在您的位置,所以我只是将所有内容都放入 Qt Creator 并从那里构建并运行该项目。

程序运行和关闭都很好,即使您建议的更改会为您破坏它。 (在带有 Qt 5.5、g++ 5.4.0 的 Ubuntu 16 上构建和运行。)

另外,我可能误解了 Igor 的评论,但由于 Application 是在堆栈上进行的,因此不会对 ~Application() 引入额外的堆释放。

【讨论】:

  • 你的回答让我深思。毕竟,我的代码似乎很好。我正在使用arch linux,我最近更新了Qt libs,看起来那里有些东西坏了。刚刚在 VirualBox (Kubuntu 16.04) 测试了应用程序,一切正常。
  • 给定的代码在您或其他系统上运行良好并不意味着没有问题。双释放内存,继续使用已经释放的对象,......不一定会导致立即失败。根据所使用的操作系统和链接库版本或用于构建这些库或应用程序本身的编译器,您对内存的使用会略有不同,这些差异可以隐藏这样一个设置上的问题,并使它们在另一个设置中可见。所以问题可能仍然存在于 OP 的代码中。 @Itha255
  • @Itha255 你确实删除了m_pixmapItem,但我注意到还有其他一些你没有删除(不这样做只是泄漏——也很糟糕,但不是你的段错误的来源,因为在程序终止之前您仍然拥有该内存)。例如,您在 image.cpp 中有 m_scene = new QGraphicsScene();,但没有相应的删除。 m_toolBar = new ToolBar(); 中的 main_window.cpp 也是如此。
  • @orphen 是的,我知道。因为我不确定 Qt 会释放什么,所以我只释放 Valgrind 告诉我的那些。
  • 好的,明白了。我们必须阅读您使用的 Qt 类的文档,以查看 Qt 是否对您可能移交给它的任何组件承担责任。另一方面,您能否偶然提供 Valgrind 堆栈跟踪,也许是对您原始问题的编辑?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 2012-10-20
相关资源
最近更新 更多