【问题标题】:QT Segfault with QString in struct global variables before main run主运行前在结构全局变量中使用 QString 的 QT Segfault
【发布时间】:2021-04-08 14:38:09
【问题描述】:

朋友们,

我有以下 structs 的代码(注意 void 指针在那里,因为它经常引用其他类似于 KCKey 的结构。为简洁起见,未显示)。

我将这些数组放置为 全局变量(我不知道最佳实践,但现在让我们一起来吧)。这些全局变量在一个标头中声明为 extern,并在其他源代码中访问。

问题出在 struct KCKey 中。当使用“keyprint”变量作为 const char * 时,它可以编译、运行并且运行良好。当使用“keyprint”变量作为 QString 时,我得到一个带有以下消息的 SEGFAULT: “下级停止了,因为它收到了来自操作系统的信号。信号名称为 SIGSEV。

代码停在“atomic_base.h”中。

为什么代码可以使用 const char * 而不是 QString。

我不认为这与内存分配有关,因为:1) 它与使用 QString 的全局变量的 ONE 实例崩溃,以及 2) 类似的代码在内存紧张的嵌入式微控制器中使用 std::string 运行良好.

struct KeyCap{
    int map;
    int row;
    int col;
    int layer;
    int keytype;
    void * void_ptr;
};


struct KCKey{
    int keycode;
    QString keyprint;
};

根据附加代码的要求: 全局头文件示例:

Map_A.h

#ifndef MAP_A_H
#define MAP_A_H

#include <QString>
#include "structs.h"

extern     KCMap Map_A;
extern     KCLayer l_aDefault;
extern     KCLayer l_aFN;
extern     KCLayer l_aNUM;

extern     KeyCap Map_A_Default[6][13];
extern     KeyCap Map_A_FN[6][13];
extern     KeyCap Map_A_NUM[6][13];

//~~~DEFAULT LAYER KEYS~~~~~~~~~~
extern     KeyCap AD_00;
extern     KeyCap AD_01;
extern     KeyCap AD_02;
extern     KeyCap AD_03;

Map_A.cpp

#include <QString>
#include "Map_A.h"
#include "keycodes.h"
#include "structs.h"

KCMap Map_A = {l_aDefault, l_aFN, l_aNUM};

KCLayer l_aDefault = {*Map_A_Default[0]};
KCLayer l_aFN = {*Map_A_FN[0]};
KCLayer l_aNUM = {*Map_A_NUM[0]};


KeyCap AD_00 = {zMap_A,0,0,1,no_key,&Key_None};
KeyCap AD_01 = {zMap_A,0,1,1,no_key,&Key_A};
KeyCap AD_02 = {zMap_A,0,2,1,no_key,&Key_B};
KeyCap AD_03 = {zMap_A,0,3,1,no_key,&Key_C};
KeyCap AD_04 = {zMap_A,0,4,1,no_key,&Key_D};

Keycodes.h

#include <QString>
#include "structs.h"
#include "keycodes.h"


KCKey Key_None = {0,""};
KCKey Key_A = {KEY_A,"A"};
KCKey Key_B = {KEY_B,"B"};
KCKey Key_C = {KEY_C,"C"};
KCKey Key_D = {KEY_D,"D"};
KCKey Key_E = {KEY_E,"E"};
KCKey Key_F = {KEY_F,"F"};
KCKey Key_G = {KEY_G,"G"};
KCKey Key_H = {KEY_H,"H"};
KCKey Key_I = {KEY_I,"I"};
KCKey Key_J = {KEY_J,"J"};
KCKey Key_K = {KEY_K,"K"};

【问题讨论】:

  • 您谈论全局变量,但代码没有显示任何内容。这些结构定义并没有什么问题——问题一定在于你如何使用它们。如需进一步帮助,请准备minimal reproducible example
  • KCMapKCLayer 是什么?您在 Map_A 的初始化程序中使用 l_aDefault 等是非常可疑的 - 它们本身此时尚未构造,定义如下。它们又依赖于更多的全局变量,例如Map_A_Default——它们在哪里以及如何定义?在不相关的注释上,您似乎是在说 keycodes.h 包含 #include "keycodes.h" 行,包括它自己;看起来不对,您显示的代码可能与您实际编译的代码不同。

标签: c++ qt memory segmentation-fault qstring


【解决方案1】:

我认为问题在于您如何使用 void_ptr。我在KCKey 结构中使用QString 尝试了从您的代码派生的代码,它可以工作。

#include <iostream>
#include <QString>

struct KCKey{
    int keycode;
    QString keyprint;
};

KCKey Key_None = {0,"test"};

int main(void)
{
    std::cout << Key_None.keyprint.toStdString() << "\n";
    return 0;
}

【讨论】:

  • 是的,这也是我的一个怀疑,但也令人困惑,因为整数、const char * 等的强制转换和取消引用工作。我可能只是坚持使用 const char *,.. 浪费了这么多我的时间
  • 我同意我认为使用 QString 代替 std::string 并没有什么好处,但是如果您需要更多帮助来查找问题,您可以附上一个最小的示例来重现该行为。
  • 感谢您的提议,.. 但是代码太大,无法用细齿梳通过,
猜你喜欢
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多