指向派生类的指针在C ++中的运行时异常中结束

问题描述 投票:0回答:3

我有一个简单的抽象基类:

class Sensor {
protected:
    GenericDriver *driver;
public:
    Sensor() {};
    virtual void startNewReadout(void) = 0;
};

从中派生出一个具体的类:

class OneWireSensor : public Sensor {
private:
    OneWireDriver oneWireDriver; //not really necessary here
public:
    OneWireSensor(PinData *pinData);
    void startNewReadout(void){
        this->driver->driverStartReadout();
    }
};

现在,当我使用以下构造函数时,我的代码将按预期方式编译并运行:

OneWireSensor::OneWireSensor(PinData *pinData) : oneWireDriver(OneWireDriver(pinData)) {
    this->driver = &oneWireDriver;
}

但是,字段oneWireDriver在我的代码中没有使用,并且我不想设置它。但是,当我从OneWireSensor类中删除它并使用如下构造函数:

OneWireSensor::OneWireSensor(PinData *pinData) {
    OneWireDriver oneWireDriver(pinData);
    this->driver = &oneWireDriver;
}

代码可以很好地编译但是执行会在运行时异常中结束(由于我是嵌入式系统,所以这是系统的硬错误)。 GenericDriver是OneWireDriver类继承的抽象类。在第二种情况下我怎么了?

c++ pointers inheritance abstract-class
3个回答
2
投票

该问题很可能是由于OneWireSensor的构造函数中悬空的指针引起的。

OneWireSensor::OneWireSensor(PinData *pinData) {

    // A function local object.
    OneWireDriver oneWireDriver(pinData);

    // Pointer to the function local object.
    // It becomes a dangline pointer as soon as the function returns.
    this->driver = &oneWireDriver;
}

您需要使用动态分配的对象。

OneWireSensor::OneWireSensor(PinData *pinData) {

    this->driver = new OneWireDriver(pinData);
}

但是您必须编写代码来管理动态分配的内存。最好使用智能指针而不是原始指针。有关智能指针的更多信息,请参见https://en.cppreference.com/w/cpp/memory


0
投票

在问题情况下,oneWireDriver仅在构造函数正在运行时存在,然后超出范围。使用任何指向它的指针都是未定义的行为。


0
投票

您正在这里创建对象:

OneWireSensor::OneWireSensor(PinData *pinData) {
    OneWireDriver oneWireDriver(pinData); //<<<------
    this->driver = &oneWireDriver;
}

在功能范围内。然后,将其地址分配给该类的成员。

功能范围结束后,oneWireDriver变量被销毁。现在,该类有了指向所有地方的迷人指针。在执行的某个时刻,您可能尝试取消引用它,从而导致RuntimeException。

您需要确保该函数结束后变量将继续存在。您可以在堆上分配它,需要记住在析构函数上进行分配。

© www.soinside.com 2019 - 2024. All rights reserved.