gpt4 book ai didi

c++ - Qt Qstring 和 SIGSEGV 段错误

转载 作者:行者123 更新时间:2023-11-28 02:23:19 32 4
gpt4 key购买 nike

从 GET_STATION_MODEL_PARAMS_t 访问 QString 类型的结构成员时,我看到了一个奇怪的段错误。执行在 ** 处停止:

代码:

#include <QDebug>
#include "hradcontroller.h"
#include "hradAPI.h"

#define TAG "HRAD_CONTROLLER:\0"
#define HRAD_API_VERSION "2"
#define MANUFACTURER_KEY "abcde12345"

typedef struct registerDeviceParams{
QString brand;
QString device;
QString manufacturer;
QString model;
QString serial;
QString ibd;
QString ibkey;
QString version;
QString track;

registerDeviceCB_t cbFn;
}REGISTER_DEVICE_PARAMS_t;

typedef struct getStationModelParams{
int stationID;
QString ibd;
QString ibkey;
QString version;
QString track;

getStationModelCB_t cbFn;

GET_STATION_MODEL_RESPONSE_t* resp;
}GET_STATION_MODEL_PARAMS_t;

HRAD *hbr = new HRAD();

void registerDevice(){
REGISTER_DEVICE_PARAMS_t params;
params.brand = "brand";
params.device = "TI-J6";
params.manufacturer = "manuf";
params.model = "EVK";
params.ibkey = MANUFACTURER_KEY;
params.serial = "abcde12345";
params.version = HRAD_API_VERSION;
params.track = "true";
params.cbFn = deviceRegisteredCB;

hbr->registerDevice(&params);
}

void getStationModel(int id){
GET_STATION_MODEL_PARAMS_t params;
params.stationID = id;
params.ibd = hbr->getId();
params.ibkey = "abdef";
params.version = "2";
** params.track = "false"; //SIGSEGV segmantation fault here
params.cbFn = stationModelAvailableCB;

params.resp = &g_StationModel;
}

void deviceRegisteredCB(QString ibd){
qDebug() << TAG << "Device Registered: ibd = " << ibd;

getStationModel(currentPublicStationID);
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/* Register ourselves to HRAD Server */

registerDevice();
}

段之前的值。故障:

enter image description here

如果您在调试时注意到“track”“不可访问”,这会导致崩溃。

我这样修改了 GET_STATION_MODEL_PARAMS_t:

typedef struct getStationModelParams{
int stationID;
QString foo; //dummy variable.
QString ibd;
QString ibkey;
QString version; //seg. fault here now
QString track;

getStationModelCB_t cbFn;

GET_STATION_MODEL_RESPONSE_t* resp;
}GET_STATION_MODEL_PARAMS_t;

值(value)观变成了这样: enter image description here

现在“版本”也“不可访问”。

知道为什么会这样吗?

谢谢。

更新 1:

工具:

Qt Creator 3.4.1 (ubuntu 14.04)

Qt 5.4.2(GCC 4.6.1,64 位)

最佳答案

TL;DR:这就是为什么您真的需要发布重现崩溃所需的所有代码。

您的代码有效 - 没有崩溃。你的问题就这样得到了回答,即使这个答案对你和其他人都毫无用处。 不要问只能以无法帮助您的方式回答的问题。

除了它是一个在现代 C++ 中没有立足之地的可怕的 C 可憎之外,在您的代码中唯一突出的是 HRAD 实例是在 main 开始执行之前创建的。根据 HRAD 的构造函数正在执行的操作,这可能是一件坏事。

但让我们看看我们是否可以修复您的代码,以指导您编写更安全的代码。

旧代码

首先,让我们逐字逐句地开始您的代码,在开头和结尾添加一些内容以使其能够编译和执行。

你应该在你的问题中提供所有这些 - 有足够的“其他东西”崩溃。下面,假设它崩溃或以其他方式重现你的问题,将被视为 sscce并使您的问题对社区有值(value)。

#include <QString>
#include <QDebug>

typedef void (*registerDeviceCB_t)(QString);
typedef void (*getStationModelCB_t)();
typedef struct getStationModelResponse {} GET_STATION_MODEL_RESPONSE_t;
void deviceRegisteredCB(QString);
void stationModelAvailableCB() {}

typedef struct registerDeviceParams REGISTER_DEVICE_PARAMS_t;
struct HRAD {
void registerDevice(REGISTER_DEVICE_PARAMS_t*);
QString getId() { return QString(); }
};

GET_STATION_MODEL_RESPONSE_t g_StationModel;
int currentPublicStationID = 1;

void registerDevice();
void getStationModel(int);
int main()
{
registerDevice();
getStationModel(0);
return 0;
}

// Your code verbatim beyond this point

您的代码,复制粘贴以供引用(显然不相关的 MainWindow 已删除):

#define TAG "HRAD_CONTROLLER:\0"
#define HRAD_API_VERSION "2"
#define MANUFACTURER_KEY "abcde12345"

typedef struct registerDeviceParams{
QString brand;
QString device;
QString manufacturer;
QString model;
QString serial;
QString ibd;
QString ibkey;
QString version;
QString track;

registerDeviceCB_t cbFn;
}REGISTER_DEVICE_PARAMS_t;

typedef struct getStationModelParams{
int stationID;
QString ibd;
QString ibkey;
QString version;
QString track;

getStationModelCB_t cbFn;

GET_STATION_MODEL_RESPONSE_t* resp;
}GET_STATION_MODEL_PARAMS_t;

HRAD *hbr = new HRAD();

void registerDevice(){
REGISTER_DEVICE_PARAMS_t params;
params.brand = "brand";
params.device = "TI-J6";
params.manufacturer = "manuf";
params.model = "EVK";
params.ibkey = MANUFACTURER_KEY;
params.serial = "abcde12345";
params.version = HRAD_API_VERSION;
params.track = "true";
params.cbFn = deviceRegisteredCB;

hbr->registerDevice(&params);
}

void getStationModel(int id){
GET_STATION_MODEL_PARAMS_t params;
params.stationID = id;
params.ibd = hbr->getId();
params.ibkey = "abdef";
params.version = "2";
params.track = "false"; //SIGSEGV segmantation fault here
params.cbFn = stationModelAvailableCB;

params.resp = &g_StationModel;
}

void deviceRegisteredCB(QString ibd){
qDebug() << TAG << "Device Registered: ibd = " << ibd;

getStationModel(currentPublicStationID);
}

// End of verbatim code

最后,registerDevice 的实现:

void HRAD::registerDevice(REGISTER_DEVICE_PARAMS_t* params) {
params->cbFn("some ibd");
}

当将这三个部分放入 main.cpp 时,将编译、运行并正确调用回调。即:

Starting bad-c-aargh-31542746...
HRAD_CONTROLLER: Device Registered: ibd = "some ibd"
bad-c-aargh-31542746 exited with code 0

返工

您似乎正在使用回调并通过指针传递值,就像您在 C 中所做的那样。我们将摆脱 C++ 中不必要的 C typedef,并且我们将利用 C++11 的功能来实现回调更有用。

如上,下面的代码只是穿插了注释。您可以将其复制粘贴到 main.cpp,删除注释,编译并运行。完成了。

首先,让我们包含 functional header 以引入 std::function,我们将摆脱 C 风格的宏:

#include <QString>
#include <QDebug>
#include <functional>

const QString TAG = QStringLiteral("HRAD_CONTROLLER:");
const QString HRAD_API_VERSION = QStringLiteral("2");
const QString MANUFACTURER_KEY = QStringLiteral("abcde12345");

然后我们将定义用于将参数传递给 HRAD 方法的结构,并从这些方法中获取响应:

struct RegisterDeviceParams {
QString brand;
QString device;
QString manufacturer;
QString model;
QString serial;
QString ibd;
QString ibkey;
QString version;
QString track;
};

struct GetStationModelParams {
int stationID;
QString ibd;
QString ibkey;
QString version;
QString track;
};

struct GetStationModelReponse {};

然后我们可以实现骨架 HRAD 类。参数作为 const 引用传递。 可选 回调可以是兼容的 lambda、仿函数实例、函数指针等。默认构造值的提供使它们成为可选的。您可以将它们从调用中删除,编译器将使用默认值。 currentPublicStationID,大概是一个全局变量,也属于 HRAD

class HRAD {
public:
void registerDevice(const RegisterDeviceParams &,
const std::function<void(const QString & ibd)> & cb
= std::function<void(const QString&)>()) {
cb("some ibd");
}

void getStationModel(const GetStationModelParams &,
const std::function<void(const GetStationModelReponse &)> & cb
= std::function<void(const GetStationModelReponse&)>()) {
GetStationModelReponse response;
cb(response);
}

QString getId() { return "some id"; }
int currentPublicStationID;
HRAD() : currentPublicStationID(1) {}
};

HRAD 的全局实例是使用 Q_GLOBAL_STATIC 宏定义的。它将在首次使用时以线程安全的方式实例化。它充当指针 - 要获取全局实例,您应该使用 -> 运算符。

Q_GLOBAL_STATIC(HRAD, hbr) // no semicolon needed

getStationModelregisterDevice 函数将使用 lambda 语法在现场实例化回调。当然,如果回调更复杂,您可以将它们放在独立的函数或方法中。

void getStationModel(int id){
GetStationModelParams params;
params.stationID = id;
params.ibd = hbr->getId();
params.ibkey = "abdef";
params.version = "2";
params.track = "false";

hbr->getStationModel(params, [](const GetStationModelReponse&){
qDebug() << "got station model";
});
}

void registerDevice(){
RegisterDeviceParams params;
params.brand = "brand";
params.device = "TI-J6";
params.manufacturer = "manuf";
params.model = "EVK";
params.ibkey = MANUFACTURER_KEY;
params.serial = "abcde12345";
params.version = HRAD_API_VERSION;
params.track = "true";

hbr->registerDevice(params, [](const QString & ibd){
qDebug() << TAG << "Device Registered: ibd = " << ibd;
getStationModel(hbr->currentPublicStationID);
});
}

最后,我们从 main 中调用 registerDevice:

int main()
{
registerDevice();
return 0;
}

此代码有效,并产生以下输出:

Starting bad-c-aargh-31542746...
"HRAD_CONTROLLER:" Device Registered: ibd = "some ibd"
got station model
bad-c-aargh-31542746 exited with code 0

请注意没有任何手动内存管理。原始指针也不被使用——既不作为参数,也不作为成员。

关于c++ - Qt Qstring <not accessible> 和 SIGSEGV 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31542746/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com