Search code examples
c++qtmemory-leakssegmentation-faultqapplication

Qt Segmentation fault at exec()


I have a very strange problem while trying to run a QProcess in a class HmiApplication, which is derived from QApplication.

The application throws a SIGSEGV in line 6 of main.cpp. This occurs only if line 11 of hmiapplication.cpp is commented out (If I don't qDebug() the stdout of the QProcess).

For the sake of simplicity and clarity, I didn't handle any return values while creating the QProcess.

main.cpp

#include "hmiapplication.h"

int main(int argc, char **argv)
{
    HmiApplication hmi(argc, argv);
    return hmi.exec(); // LINE 6 - SIGSEGV
}

hmiapplication.h

#ifndef HMIAPPLICATION_H
#define HMIAPPLICATION_H

#include <QApplication>
#include <QProcess>

class HmiApplication : public QApplication
{
    Q_OBJECT
public:
    HmiApplication(int argc, char **argv);
    virtual ~HmiApplication();

private:
    QProcess *macFinder = nullptr;
};

#endif // HMIAPPLICATION_H

hmiapplication.cpp

#include "hmiapplication.h"

HmiApplication::HmiApplication(int argc, char **argv) : QApplication(argc, argv)
{
    macFinder = new QProcess(this);
    macFinder->start("arping", QStringList() << "-c 2" << "192.168.1.1");
    macFinder->waitForReadyRead();
    QString ret(macFinder->readAllStandardOutput());
    ret = ret.mid(ret.indexOf('[') + 1, 17);
    qDebug() << ret; // LINE 11
}

HmiApplication::~HmiApplication()
{
}

EDIT: If I add QVector<Camera*> cameras; to the header and

for(quint8 i = 0; i < 10; i++) {
    Camera *cam = new Camera(i);
    cameras.append(cam);
}

to the source file, it doesn't matter whether or not I remove the qDebug() line and will throw a segmentation fault in both cases.

Camera is a derived class of QLabel and is perfectly working without the QProcess mentionened above.


Solution

  • The QApplication constructor accepts its first parameter by reference...

    QApplication::QApplication(int &argc, char **argv)
    

    With the documentation also warning that...

    The data referred to by argc and argv must stay valid for the entire lifetime of the QApplication object. In addition, argc must be greater than zero and argv must contain at least one valid character string.

    However, you pass argc by value to the HmiApplication. Hence the QApplication constructor receives a non-const reference to the local copy which will go out of scope at the end of the HmiApplication ctor leading to undefined behaviour later on.

    Change the signature of your constructor to...

    HmiApplication::HmiApplication(int &argc, char **argv)