尝试访问特定类型的指针

时间:2016-01-13 02:43:57

标签: c++ qt pointers

最终编辑:

事实证明没有问题,除了我应该写 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;
    }
    //...
    }

1 个答案:

答案 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/