Segfault when accessing QApplication::arguments

1k Views Asked by At

While writing a program including qt for gui, I stumbled upon a problem, which can be reproduced with the minimum code below:

#include <iostream>
#include <QApplication>
#include <QSettings>

using namespace std;

int main(int argc, char ** argv) {
    QApplication *app;
    {
        int tmp_argc = argc;
        app = new QApplication(tmp_argc, argv);
    }
    QSettings settings("testvendor");
    cout<<"Num of arguments: "<<app->arguments().count()<<std::endl;
    return 0;
}

Running results in either core dump (in the call to QApplication::arguments) or Num of arguments: 0 which is obviously wrong.

If I instantiate app with app = new QApplication(argc, argv) (using unscoped variable with the count of arguments) OR remove the declaration/definition of settings - the program outputs Num of arguments: 1 as expected (any one of these changes is sufficient).

I use Qt 5.5 on Ubuntu, the project is cmake-based, the contents of CMakeLists.txt:

cmake_minimum_required(VERSION 3.3)
project(qtest)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(CMAKE_PREFIX_PATH /opt/Qt/6.5.1/gcc_64/)
find_package(Qt5Widgets REQUIRED)

set(SOURCE_FILES main.cpp)
add_executable(qtest ${SOURCE_FILES})
target_link_libraries(qtest Qt5::Widgets)
2

There are 2 best solutions below

4
On BEST ANSWER

Warning: 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."

From QT 5 Documentation. Emphasis mine.

tmp_argc goes out of scope.

QApplication *app;
{
    int tmp_argc = argc;
    app = new QApplication(tmp_argc, argv);
} <-- BOOM!
1
On

Here's how to fix it, in line with requirements given in the documentation of QCoreApplication constructor:

// https://github.com/KubaO/stackoverflown/tree/master/questions/app-args-35566459
#include <QtCore>
#include <memory>

std::unique_ptr<QCoreApplication> newApp(int & argc, char ** argv) {
   return std::unique_ptr<QCoreApplication>(new QCoreApplication{argc, argv});
}

int main(int argc, char ** argv) {
    std::unique_ptr<QCoreApplication> app(newApp(argc, argv));
    QSettings settings{"testvendor"};
    qDebug() << "Num of arguments: " << app->arguments().count();
}