首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++,Qt4 - QLabel.setText()似乎会导致分割错误

C++,Qt4 - QLabel.setText()似乎会导致分割错误
EN

Stack Overflow用户
提问于 2016-05-09 18:18:08
回答 2查看 1K关注 0票数 0

编辑:问题解决了,见我的答案。TL;DR:与Qt无关,我在数组(std::vector)范围上犯了一个愚蠢的错误。

使用Windows7,Qt版本4.8.7,x86_64-w64-mingw32-g++作为编译器,Cygwin用于编译,Notepad++用于编辑。(同样的项目中也有Flex和Bisonc++,但它们与问题无关,而且工作正常。)

我有一个std::vector< QLabel* >,我尝试用数据填充它。在一个测试用例(即包含向量的QFrame )中,从主函数获取数据,而不涉及其他类),效果很好,就像预期的那样。

在另一种情况下,当使用QMainWindow来触发调用相同函数的自己的时隙方法时,它在QLabel.setText( QString::number() )部分会遇到一个分段错误。

ui_parts.h

代码语言:javascript
复制
#ifndef UI_PARTS_H_INCLUDED
#define UI_PARTS_H_INCLUDED

#include <QWidget>
#include <QLabel>
#include <QGridLayout>
#include <QFrame>
#include <vector>
#include <string>

class regDisplay : public QFrame{
Q_OBJECT
public:
  regDisplay(int _meret, const std::string &nev, QWidget *parent = 0);
  ~regDisplay() {};  // not actually in the header, here for compression
  int size() const { return meret; };
  void setValues(const std::vector<AP_UC> &val);
private:
  QGridLayout* gridLayout;
  int meret;
  std::vector<unsigned char> valueVec;
  std::vector<QLabel*> valueLabel;
};

#endif  // UI_PARTS_H_INCLUDED

ui_parts.cpp

代码语言:javascript
复制
#include <iostream>
#include "ui_parts.h"
using namespace std;

regDisplay::regDisplay(int _meret, const std::string &nev, QWidget *parent)
 : QFrame(parent), name(nev), meret(_meret){
  valueVec.resize(meret, 0);
  valueLabel.resize(meret, NULL);
  gridLayout = new QGridLayout(this);
  // [...] setting up other properties of the widget
  for (int i = 0; i < meret; ++i){
    valueLabel[i] = new QLabel(this);
    // [...] set properties for valueLabel[i]
    gridLayout -> addWidget( valueLabel[i], 1, i);
  }
}

// the following function which is suspected with causing the segfault
void regDisplay::setValues(const std::vector<AP_UC> &val){
  for (int i = 0; i < meret; ++i)
  {
    valueVec[i] = val[i];
    cout << (int)valueVec[i] << "\t" << (QString::number( (int)valueVec[i] )).toStdString() << endl;
    cout << "ptr: " << (valueLabel[i]) << endl;
    if ( valueLabel[i] == NULL ){
      cout << "NULL POINTER? WTF " << i << endl;
    } else{
      cout << "not null pointer " << i << endl;
    }
    cout << "kek" << endl;
    valueLabel[i] -> setText( QString::number( (int)valueVec[i] ));    // SEGFAULT
    cout << i << "+" << endl;
  }
}

调用该函数:

代码语言:javascript
复制
vector<unsigned char> vecUC(4);
allapot.get_reg("eax", vecUC);   // I'm 100% sure this works correctly, tested thoroughly
  // it makes vecUC equal to an std::vector<unsigned char> which is 4 long
eax -> setValues( vecUC );  // regDisplay* eax;
         // initialized: eax = new regDisplay(4, "eax", this ); in the constructor of this class (which inherits from QMainWindow)

这段代码的控制台输出:

代码语言:javascript
复制
0       0
ptr: 0x32f160
not null pointer 0
kek
Segmentation fault

我对此的解读:

valueVeci及其QString版本都是0( setText()的参数似乎很好)

valueLabeli的指针值不是0,因此在构造函数中初始化为valueLabeli不是空指针(本例中为== 0)

第一个cout在setText()之前工作,第二个cout不工作

从整个代码中删除(注释) setText()调用可以使它正常工作(但我需要某种方式在UI上输出文本,因此为了程序的目的,需要以某种形式使用它们)。

“makeui_vec”为regDisplay和veremDisplay类创建测试模块,运行良好

“makeui_main”为mainDisplay创建了测试模块,这将导致出现问题

我不知道是什么原因造成了这个问题,我希望有任何帮助来消除它。提前谢谢你。

更新(16.05.14):

我在wxWidgets中重新创建了整个项目,它的工作原理非常相似,但基本上在同一时刻,它也开始抛出分段错误。它似乎是随机发生的,有时整个程序工作正常,有时在第一个动作上失败。

但是,通过gdb运行程序完全解决了这个问题,我没有遇到任何分段错误。

Update (16.05.16):经过一些进一步的测试,问题似乎出现在我创建的bisonc++ / flex解析器中。有一段使用它的代码每次都能很好地工作,如果我尝试添加它(带std::stack返回到以前的状态;使用类导航),那么在第二条指令之后就会出现分段错误(第一条很好)。

脚注:

存储库链接 -问题出现在src/cpp/ui_parts.cpp line79 (regDisplay::setValue())中,从mainDisplay::displayAllapot()调用(src/cpp/ui_main.cpp line195)。调试消息可能发生了一些变化,其余的代码是相同的。

大部分文件和注释是用匈牙利文而不是英文写的,我对此表示歉意。

另一个(可能相关的问题):相同的程序有时会在不同的位置遇到相同的分段错误--有时回显::setValue()运行得很好,问题出现在veremDisplay::updateValue()--在循环中,可能在第一次运行时,有时在整个过程中运行,但我还没有看到其中的任何一致性(它在第一次运行时基本停止运行)。

第三个问题(同样,很可能与此相关):当调用openFile()函数时,它会正常运行到最后(最后一条指令是调试消息,并且工作正常),但是会给出一个seg错误(这会让我想到析构函数问题)。但是,如果我将一个不同的函数( oF2() )连接到同一个事件,然后让oF2()调用openFile()并编写调试消息(其他什么都不写),那么调试消息就会显示,然后就会出现分段错误--并且没有接收到局部变量或参数,所以在代码的最后一条指令和终止函数之间不应该运行析构函数。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-16 17:33:54

我发现了这个问题,我在std::向量中找到了10个,它的大小只有7个(只出现在一些测试用例中),修复了解决了所有问题的所有问题,到目前为止还没有在相当广泛的测试中出现分段错误。

由于真正的问题在任何方面都与Qt无关(也不涉及bisonc++或flex),所以除了“检查数组范围”课程外,我认为没有任何真正的理由让这个线程继续存在。如果mods看到了这一点,请随意删除这个问题--如果解决方案不足以继续下去的话。

票数 1
EN

Stack Overflow用户

发布于 2016-05-09 20:37:48

我不认为您的代码问题可能会导致分段错误。

但我猜您的编译标志可能会导致这样的分段错误。

例如,您使用std::stringtoStdString

如果Qt是用另一个版本的编译器编译的,或者例如,如果您将程序静态地链接到c++ runtime library (您确实使用makefile-静态-libgcc-静态-libstdc++链接)和Qt链接到c++ runtime的dll变体,那么您的程序和Qt库可能会认为它们与相同版本的std::string一起工作,但实际上,当您在程序中调用std::string的析构函数时,在Qt中分配的std::string可能会导致分段错误。或者使用由QFile创建的FILE *创建fopen,然后在~QFile中捕获分段错误,因为Qt FILEFILE是不同的。

因此,请确保您的Qt编译时使用与您的程序相同的编译器,而Qt则使用与您的程序相同的标志构建。

实际上,sizeof(std::string)sizeof(FILE)可能是相同的,但是可以使用不同的分配器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37122755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档