在从QString访问GET_STATION_MODEL_PARAMS_t类型的struct成员时,我看到一个奇怪的分段错误。
代码:
#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(¶ms);
}
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();
}值就在seg之前。过失:

如果注意到“跟踪”在调试时“不可访问”,则会导致崩溃。
我对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;价值观变成了这样:

现在“版本”也是“不可访问的”。
知道为什么会这样吗?
谢谢。
更新1:
工具:
Qt Creator 3.4.1 (ubuntu 14.04)
Qt 5.4.2 (GCC 4.6.1,64位)
发布于 2015-07-21 16:23:33
TL;DR:这就是为什么您确实需要发布再现崩溃所需的所有代码。
你的代码有效-没有崩溃。你的问题就这样回答了,即使答案对你和其他人都是完全无用的。不要问那些只能以一种无法帮助你的方式回答的问题。
除了在现代C++中没有位置的可怕的C类之外,在您的代码中唯一突出的地方是在main开始执行之前就创建了HRAD实例。取决于HRAD的构造函数在做什么,这可能是一件坏事。
但是,让我们看看我们是否可以修复您的代码,以指导您编写更安全的代码。
旧码
首先,让我们从代码逐字开始,在开头和结尾添加一些内容,以使其编译和执行。
你应该在你的问题中提供所有这些--有足够的“其他东西”让你崩溃。假设它崩溃或以其他方式重现了你的问题,下面的将被视为斯考斯,并使你的问题对社区有价值。
#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(¶ms);
}
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类型,我们将利用C++11的特性使回调更加可用。
如前所述,下面的代码仅仅是与评注交织在一起。您可以将其复制粘贴到main.cpp中,删除注释,编译并运行。它已经完成了。
首先,让我们包括functional头以引入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 neededgetStationModel和registerDevice函数将使用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注意,没有任何手动内存管理。原始指针也不作为参数使用,也不作为成员使用。
https://stackoverflow.com/questions/31542746
复制相似问题