我有一个qt GUI应用程序,它包含一个从QFrame派生的小部件DS9,用于打开和操作外部程序。该类的实现如下所示:
ds9.h
#ifndef DS9_H
#define DS9_H
#include <QFrame>
#include <QProcess>
class DS9 : public QFrame
{
Q_OBJECT
public:
explicit DS9(QWidget *parent = 0);
~DS9();
signals:
public slots:
void runDS9();
private:
QProcess *ds9;
};
#endif // DS9_H
ds9.cpp
DS9::DS9(QWidget *parent):
QFrame(parent)
{
ds9 = new QProcess();
ds9->setProgram("ds9");
QStringList arguments;
arguments << "-invert" << "-zscale";
ds9->setArguments(arguments);
}
DS9::~DS9()
{
delete ds9;
}
void DS9::runDS9()
{
ds9->start();
}
但是,在运行程序时,不会显示GUI,而是会出现黑色(非空白)窗口并立即崩溃。错误消息如下所示:
*** Error in `./lightcurve_examiner': double free or corruption (out): 0x00000000013f0610 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x77a8d)[0x7f0a9dcada8d]
/lib64/libc.so.6(cfree+0x5cd)[0x7f0a9dcb9d2d]
/lib64 /libQt5Core.so.5(_ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11Q ThreadData+0x2d0)[0x7f0a9efd0a20]
/lib64/libQt5Core.so.5(+0x2d9983)[0x7f0a9f024983]
/lib64/libglib-2.0.so.0(g_main_context_dispatch+0x15a)[0x7f0a9d2eca8a]
/lib64/libglib-2.0.so.0(+0x49e20)[0x7f0a9d2ece20]
/lib64/libglib-2.0.so.0(g_main_context_iteration+0x2c)[0x7f0a9d2ececc]
.....
但是,如果我没有将QProcess *ds9
设置为班级成员,即执行以下操作:
在.h:
...
private:
// QProcess *ds9;
...
in .cpp:
void DS9::runDS9()
{
QProcess * ds9 = new QProcess();
ds9->setProgram("ds9");
QStringList arguments;
arguments << "-invert" << "-zscale";
ds9->setArguments(arguments);
ds9->start();
}
一切正常,即GUI正常启动,通过调用插槽,正确调用程序。
我的问题是,为什么我不能把QProcess对象作为类的成员?如果确实如此,我如何保留指针并访问/重用它?
谢谢!
答案 0 :(得分:1)
对我来说,看起来DS9对象的生命周期可能存在问题,即它太快被删除,因此您的代码问题在您的类外部。前几天我遇到了同样的问题,问题在于我的可疑测试代码创建了一个在调用QApplication :: exec()之前删除的QProcess。我建议,如果你还没有尝试过这个,你从QProcess派生一个类并向它的析构函数和DS9的析构函数添加一个日志调用,或者看看你是否可以在这些析构函数中添加断点并查看流程您的程序外部。另外,作为额外的一点,您可能希望将构造函数调用更改为QProcess以将DS9对象添加为父对象,这将使您不必在DS9的析构函数中手动调用delete。
祝你好运:)