我正在 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 编译的
你有一个基本的设计缺陷。在你的
void ControllerT1::setState(IControllerStateT1* newState) {
delete currentState;
currentState = newState;
currentState->handle(this);
}
您首先删除
currentState
,然后分配一个新的,然后调用处理。现在,调用 currentState->handle(this);
可以到达 controller->setState(new Intermediate());
例程内的 handle
,而这又可以到达 delete
方法 handle
仍未返回的对象,从而导致未定义的行为(在您的情况下崩溃)。
如果您处理引用而不是指针并将状态对象保留在状态机内,那就更好了。