最终编辑:
事实证明没有问题,除了我应该写 ui-> lineEdit_decviceName 而不是 ui-> label_decviceName ,否则我永远不会得到正确的输入。并且检查右输入是否在此函数之外,所以我几乎进入无限循环。每个人都应该知道拼写错误,它可能会伤害你。
所以我尝试使用Qt4.8,QtCreator和第三方库(这个lib很好)实现登录过程。
在主程序中,我定义了一个类的指针:
DeviceData* m_gcurrentdevicedata;
并将其传递给Login对象:
m_loginandadddevice = new LoginAndAddDevice(..., m_gcurrentdevicedata, ...);
此Login类的构造函数定义:
LoginAndAddDevice(..., DeviceData* currentdevicedata, ....);
在Login类的构造函数中,我将此指针传递给另一个相同类型的指针:
this->logincurrentdevicedata = currentdevicedata;
在此之后,我为该指针的对象赋值:
logincurrentdevicedata = &(*it); ('it' is an iterator)
所以现在我假设主程序中的变量 gcurrentdevicedata 在Login对象中具有相同的 logincurrentdevicedata 的地址和值。(我可以从 logincurrentdevicedata 没有错误)
但是,当我尝试从主程序中的 gcurrentdevicedata 获取值时,整个程序崩溃了。 我可以猜测指针 logincurrentdevicedata 与 gcurrentdevicedata 没有相同的地址或值。但为什么以及如何克服它呢?非常感谢提前。
更多细节:
void LoginAndAddDevice::on_pushButton_login_clicked()
{
QString name = ui->label_decviceName->text().trimmed();
QList<DeviceData>& listDeviceDataref = *devicedatalist; //assign this pointer to a reference
int & useridref = *userID; //assign this pointer to a reference
QList<DeviceData>::iterator it;
for(it = listDeviceDataref.begin();it!=listDeviceDataref.end();++it)
{
if(((*it).getDeviceName() == name) && !name.isEmpty())
{
break;
}
}
qDebug()<<"after login button pressed "+QString::number((*it).getUsrID());
DeviceData& devicedataref = (*it); //here I assign the pointer value to a reference value
if(devicedataref.m_iuserid>=0)
{
qDebug()<<"after login button pressed, before set the value "+QString::number((*it).getUsrID());
useridref = devicedataref.getUsrID();
qDebug()<<"after login button pressed, before set the deviceinfo value "+QString::number(*userID);
m_logindeviceinfo = &(devicedataref.m_deviceinfo);
qDebug()<<"after login button pressed, before set the currentdevicedata value "+QString::number(*userID);
*logincurrentdevicedata = devicedataref; //this line leads to crash, prior code works fine
qDebug()<<"12121";
qDebug()<<"logincurrentdevicedata's user id: "+ QString::number(logincurrentdevicedata->getUsrID());
ui->pushButton_cancel->setText(tr("Ok"));
return;
}
//...
}
答案 0 :(得分:1)
在像STL这样的现代C ++库中,以下既不保证获得地址也不保证安全:
logincurrentdevicedata = &(*it); // ('it' is an iterator)
有可能使用此表达式获取临时地址或集合删除/移动项目。但是,有些容器实现/用例可以通过这种方式获取集合项的地址:然后,当项目消耗时,集合需要保持不变。
虽然有可能工作,但不知道迭代器和容器类型的细节,我们不能肯定地说。这个容器的生命周期都不清楚。您还需要确保该迭代器有效,并且不指向其集合的结尾。
您可以改为创建该对象的副本:
auto it = collection.begin(); // OR can be an arbitrary iterator
if (it != collection.end())
auto val = *it; // make sure that new object is available
// if you pass an address of it to somewhere.
或者您可以将对该集合的引用传递给使用者:
void consumer(std::list<T>& collection)
{
auto it = collection.begin(); // OR can be an arbitrary iterator
if (it != collection.end())
it->access(); // now it supposed to be safe
}
P.S。在这个问题的作者提供了一个例子之后,事实证明这个变量实际上是一个指针,并且赋值给它指向的实际值:
*logincurrentdevicedata = devicedataref; // copying an object here
在这里你被解除引用&#39;指针并使其指向对象并按值进行赋值。代码仍然不足,因为不清楚logincurrentdevicedata指针是否包含DeviceData对象的实际地址。
为了使它工作,它必须满足:
DeviceData deviceData;
DeviceData* logincurrentdevicedata = &deviceData;
或者:
DeviceData* logincurrentdevicedata = new DeviceData;
问题似乎与基本C有关,从这一点来看,我们无法确定该代码中可能不正确的其他内容。我在代码中看到了其他几个可疑点,但这样的问题可能只适用于https://codereview.stackexchange.com/