传入函数时C ++ shared_ptr有趣的行为(已解决但好奇)

时间:2018-01-23 22:21:47

标签: c++ malloc runtime-error shared-ptr

背景

我正在为涉及模拟大量State Space数学模型的项目编写一些C ++代码。因为有几种不同类型的模型存在不同程度的复杂性(即非线性/线性和时变/非变化)我创建了一个能够表示的多态类结构每种类型的各种功能,同时仍然很好地保持矩阵的共同属性捆绑在一起。通过这种方式,我可以轻松地将各种模型类型推广到OdeInt内部进行模拟。

简单基类的当前版本如下所示:

class SS_ModelBase
{
public:
    virtual Eigen::MatrixXd getA() = 0;
    virtual Eigen::MatrixXd getB() = 0;
    virtual Eigen::MatrixXd getC() = 0;
    virtual Eigen::MatrixXd getD() = 0;
    virtual Eigen::MatrixXd getX0() = 0;

    virtual int getNumInputs() = 0;
    virtual int getNumOutputs() = 0;
    virtual int getNumStates() = 0;

private:
};
typedef boost::shared_ptr<SS_ModelBase> SS_ModelBase_sPtr;

所提及类型的每个派生类然后具有它们自己的变量,用于实际存储矩阵A,B,C,D和&amp;的特定表示。 X0。输入,输出,状态用于某些尺寸信息,这些信息可能需要以后进行操作。在实践中,这对我来说非常好。

我将如何在模拟器中使用模型的示例如下所示:

Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt, 
    const SS_ModelBase_sPtr& model, const PID_Values pid)
{
    /* Due to how Odeint works internally, it's not feasible to pass in a full state space model object 
    and run the algorithm directly on that. (Odeint REALLY dislikes pointers) Instead, a local copy of the 
    model will be made. For now, assume that only NLTIV models are handled. */
    SS_NLTIVModel localModel(model);

    /* Copy the relevant data from the model for cleaner code in main sim*/
    Eigen::MatrixXd x = localModel.getX0();
    Eigen::MatrixXd A = localModel.getA();
    Eigen::MatrixXd B = localModel.getB();
    Eigen::MatrixXd C = localModel.getC();
    Eigen::MatrixXd D = localModel.getD();

 //Other irrelevant code that actually performs numerical simulations
}

上面代码中的自定义复制构造函数如下所示:

/* Copy constructor */
    SS_NLTIVModel(const SS_ModelBase_sPtr& base)
    {
        inputs = base->getNumInputs();
        outputs = base->getNumOutputs();
        states = base->getNumStates();

        A.resize(states, states); A.setZero(states, states);
        B.resize(states, inputs); B.setZero(states, inputs);
        C.resize(outputs, states); C.setZero(outputs, states);
        D.resize(outputs, inputs); D.setZero(outputs, inputs);
        X0.resize(states, 1); X0.setZero(states, 1);
        U.resize(inputs, 1); U.setZero(inputs, 1);
    }

问题

我在一些模拟中注意到,在尝试调整各种矩阵的大小时,我会在复制构造函数中获得内存访问冲突错误。 std :: malloc()在Eigen框架中深入调用并抛出错误。经过几个小时撞击墙壁试图找出为什么Eigen软件突然无法正常工作,我偶然发现 解决方案,但我不知道它为什么会起作用或者是否有效更好的方式。

我旧的已损坏的功能签名如下所示:

Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt, 
    SS_ModelBase_sPtr model, PID_Values pid)

新的工作功能签名如下所示:

Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt, 
    const SS_ModelBase_sPtr& model, const PID_Values pid)

这两者之间的运行时差异可能导致我的错误?我知道第一个会增加shared_ptr的参考计数器而第二个不会增加,但除此之外,我不确定什么会改变行为足以引起我的问​​题...想法?

0 个答案:

没有答案