创建 QtChart 对象会在运行时创建 EXC_BAD_ACCESS 错误

Posted

技术标签:

【中文标题】创建 QtChart 对象会在运行时创建 EXC_BAD_ACCESS 错误【英文标题】:Creation of QtChart object creates EXC_BAD_ACCESS error upon runtime 【发布时间】:2018-09-27 12:11:49 【问题描述】:

出于实践原因,我目前正在尝试将一些代码从 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 对象存在问题,在该对象中我不断收到调试器所述的以下异常:

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)给出的方式,在他们的资源中额外研究并没有导致任何解决方案。有没有人知道该怎么做?

qtflags.h(Qt 库的一部分)
Q_DECL_CONSTEXPR inline QFlags(Zero = Q_NULLPTR) Q_DECL_NOTHROW : i(0) 

但是调试器的堆栈跟踪表明对象创建成功。

stack trace of debugger

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

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

【问题讨论】:

您能否提供更多信息。这样,我无法弄清楚实际问题。能否请您提供完整的源代码。 为您编辑了它,希望这可以澄清您的询问。 一方面 getline 没有给出包含分隔符的字符串,因此您需要在执行 pop_back 之前检查“line”中的实际内容 是的,谢谢,我已经想通了,但这并不重要,因为在创建 QChart 对象时不使用结果向量,这就是应用程序失败的地方 【参考方案1】:

你没有任何 QApplication 实例。

这是来自 Qt Docs 的引述:

QApplication 类管理 GUI 应用程序的控制流和 主要设置。

QApplication 包含主事件循环,其中所有来自 窗口系统和其他来源被处理和调度。它也是 处理应用程序的初始化、终结,并提供 会话管理。此外,QApplication 处理大部分 系统范围和应用程序范围的设置。

对于任何使用 Qt 的 GUI 应用程序,只有一个 QApplication 对象,无论应用程序是否有 0、1、2 个或更多窗口 在任何给定时间。对于非 GUI Qt 应用程序,使用 QCoreApplication 相反,因为它不依赖于 QtGui 库。

可以通过 instance() 函数访问 QApplication 对象 它返回一个与全局 qApp 指针等效的指针。

所以,这条线

QApplication app(argc, argv);

创建一个 QApplication 类的实例。

最后你需要调用app.exec(),它进入主事件循环并等待直到exit()被调用,然后返回设置为exit()的值(如果exit()被调用,则返回0退出())。

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

【讨论】:

非常感谢@sonulohani!这解决了问题,我现在得到了我的图表。

以上是关于创建 QtChart 对象会在运行时创建 EXC_BAD_ACCESS 错误的主要内容,如果未能解决你的问题,请参考以下文章

Swift 解析 Facebook Graph API 对象时出错:EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP)

printf 导致 EXC_BAD_ACCESS(code=EXC_I386_GPFLT) 警告并在运行时冻结

错误:“线程 1:EXC_BAD_ACCESS(代码=EXC_I386_GPFLT)

从 Parse.com (Swift) 检索数据

代码=exc_i386_invop 子代码=0x0 笔尖 xcode7.2

当您在不指定对象类型的情况下创建 ArrayList 时,它会在您添加第一个对象时自动创建它吗?