创建 QtChart object 会在运行时产生 EXC_BAD_ACCESS 错误

Creation of QtChart object creates EXC_BAD_ACCESS error upon runtime

出于实践原因,我目前正在尝试将一些代码从 Python 移至 C++,并尝试使用 QtCharts 库创建折线图。 我在他们的网站上使用 Qt 提供的 Qt 开源安装程序安装了 Qt 库,并最终成功地将库包含在 Clion 的项目中,代码如下:

CMakelist.txt

cmake_minimum_required(VERSION 3.12)
project(Uebung1)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Qt
# Set this to your Qt installation
set(CMAKE_PREFIX_PATH /Users/DaniBook/Qt/5.11.2/clang_64)
set(RESOURCE_FOLDER res)
set(RESOURCE_FILES ${RESOURCE_FOLDER}/resources.qrc)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

find_package(Qt5Charts CONFIG REQUIRED)

set(PROJECT_SOURCE_DIR src/)
include_directories(${PROJECT_SOURCE_DIR})
add_executable(Uebung1 src/main.cpp src/tools.h src/tools.cpp)
target_link_libraries(Uebung1 Qt5::Charts)

到目前为止一切顺利,我可以在我的代码中使用这个库,它基本上由两个函数组成。一种从文件中读取数据并将其转换为整数向量,另一种采用该向量并尝试创建 Qt 折线图。

tools.cpp

#include "tools.h"
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <QtCharts>
#include <fstream>

using namespace std;

void GC_skew(vector<long> &gc_data, string &genome_file) {
    ifstream gfile(genome_file);
    string line;
    long g_sum = 0, c_sum = 0;

    if(gfile.is_open()) {
        //reading file line by line
        while(getline(gfile, line)) {
            //iterating over string characters to count G and C
            for(auto &character : line) {
                switch(character) {
                    case 'G' :
                        g_sum++;
                        break;
                    case 'C' :
                        c_sum++;
                        break;
                    default :
                        continue;
                }
                //appending skew to vector
                gc_data.push_back(g_sum - c_sum);
            }
        }
    }
    else {
        cout << "Unable to open file!" << endl;
    }
}

void skew_chart(vector<long> &gc_data) {
    auto *series = new QLineSeries();//creating new series object
    auto *chart = new QChart();              //creating new chart object
    auto *chartview = new QChartView(chart); //creating chartview object
    QMainWindow window;                     //window object for display
    long pos = 0;

    //iterating over the vector and appending data to series
    for(auto it : gc_data) {
        series->append(pos, it);
        pos++;
    }

    //adding series to chart and viewing chart
    chart->addSeries(series);
    chartview->setRenderHint(QPainter::Antialiasing);
    window.setCentralWidget(chartview);
    window.show();
}

main.cpp

#include <iostream>
#include "tools.h"
#include <vector>
#include <map>

using namespace std;

int main() {
    vector<long> gc_data = {};
    string genome_file = "<path_to_file>";

    GC_skew(gc_data, genome_file);
    skew_chart(gc_data);
}

代码编译没有错误,但是当 运行 它以退出代码 11 终止(无论那是什么意思)。但是,在调试时我发现创建新 QChart object 存在问题,我不断收到调试器所述的以下异常:

Exception = error: use of undeclared identifier 'Exception' //occurs somewhere before the one below but does not effect the application
Exception = EXC_BAD_ACCESS (code=1, address=0x0) //causes the application to crash

Debug information

上面的初始化方式正是Qt给出的方式(https://doc.qt.io/qt-5/qtcharts-linechart-example.html) 进一步研究了他们的资源并没有找到任何解决方案。你们中有人知道该怎么做吗?

P.S.: 通过逐行检查,我发现在初始化时跳转到了 header,这似乎定义了一个在任何事件

时都会引发的异常

qtflags.h(Qt 库的一部分)

Q_DECL_CONSTEXPR inline QFlags(Zero = Q_NULLPTR) Q_DECL_NOTHROW : i(0) {}

然而,调试器的堆栈跟踪表明 object 创建成功。

stack trace of debugger

Qt版本为5.11.2 编译器版本 Apple LLVM 版本 10.0.0 (clang-1000.11.45.2)

如果有人能理解这一点,请提前致谢

您没有任何 QApplication 实例。

引用自 Qt Docs:

The QApplication class manages the GUI application's control flow and main settings.

QApplication contains the main event loop, where all events from the window system and other sources are processed and dispatched. It also handles the application's initialization, finalization, and provides session management. In addition, QApplication handles most of the system-wide and application-wide settings.

For any GUI application using Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any given time. For non-GUI Qt applications, use QCoreApplication instead, as it does not depend on the QtGui library.

The QApplication object is accessible through the instance() function that returns a pointer equivalent to the global qApp pointer.

所以,行

QApplication app(argc, argv);

创建 QApplication 的一个实例 class。

最后你需要调用 app.exec() 进入主事件循环并等待直到 exit() 被调用,然后 returns 设置为 exit() 的值(即0 如果通过 quit() 调用 exit())。

需要调用此函数来启动事件处理。主事件循环从 window 系统接收事件并将这些事件分派给应用程序小部件。