C++ 中的状态模式实现遇到分段错误

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

我正在 C++ 中实现状态模式,通常一切正常并且根据需要工作,但是在状态多次更改后我出现分段错误,堆栈分配不断上升直到达到最大值然后崩溃 雇用代码: 接口:

class ControllerT1; // Forward declaration

class IControllerStateT1 {
public:
    virtual ~IControllerStateT1() {}
    virtual void handle(ControllerT1* controller) = 0;
};



class ControllerT1 {
    public:
        ControllerT1(std::vector<int> &input, std::vector<int> &output);
        ~ControllerT1();

        void stop();
        void initialize();
        void run();

        void setState(IControllerStateT1* newState);

    private:
        IControllerStateT1* currentState;
};


#include "ControllerT1.h"
#include "StopT1.h"

ControllerT1::ControllerT1(std::vector<int> &input, std::vector<int> &output) : currentState(new StopT1()) {
//  ControllerInputs = input;
//  ControllerOutputs = output;
}

ControllerT1::~ControllerT1() {
    delete currentState;
}

void ControllerT1::run() {
    currentState->handle(this);
}

void ControllerT1::stop() {
    currentState->handle(this);
}

void ControllerT1::initialize() {
    //std::cout << "Reading Confihuration files" << std::endl;
    currentState->handle(this);
}

void ControllerT1::setState(IControllerStateT1* newState) {
    delete currentState;
    currentState = newState;
    currentState->handle(this);
}

状态示例:

class RunningT1 : public IControllerStateT1 {
public:
    RunningT1();
    void handle(ControllerT1* controller) override;
};

RunningT1::RunningT1() {

}

void RunningT1::handle(ControllerT1* controller) {

    std::cout<<"Bettery api 1 runing"<<std::endl;
try {
    std::lock_guard<std::mutex> lock(DataMutex);
    for (auto& element: ControllerOutputs) {
        element=element+1;
    }

} catch (const std::exception&  e) {
    std::cerr<<e.what()<<std::endl;
}
    std::this_thread::sleep_for(std::chrono::milliseconds(30));



    controller->setState(new Intermediate());
}

我怀疑这部分代码会产生问题

void ControllerT1::setState(IControllerStateT1* newState) {
    delete currentState;
    currentState = newState;
    currentState->handle(this);
}

但我不知道如何更改它,我试图在那里使用指针,例如:

std::unique_ptr<IControllerStateT1> newState

避免使用 new 关键字,但问题是一样的 如果有任何建议,我将不胜感激 程序是为 QNX x86_64 编译的

c++ state qnx
1个回答
0
投票

你有一个基本的设计缺陷。在你的

void ControllerT1::setState(IControllerStateT1* newState) {
    delete currentState;
    currentState = newState;
    currentState->handle(this);
}

您首先删除

currentState
,然后分配一个新的,然后调用处理。现在,调用
currentState->handle(this);
可以到达
controller->setState(new Intermediate());
例程内的
handle
,而这又可以到达
delete
方法
handle
仍未返回的对象,从而导致未定义的行为(在您的情况下崩溃)。

如果您处理引用而不是指针并将状态对象保留在状态机内,那就更好了。

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