For a task, I am planning to implement a state machine in C . I am trying to keep a context object which provides following:
- a state_ object to keep track of current state
- a TransitionTo() method to facilitate transition to new state.
When I wrote the sample implementation and tested it out, I am facing double free error.
I needed help from the community in guiding me on what might be going wrong. Thanks a lot.
#include <iostream>
#include <string>
class State;
/* Context class and method implementation */
class Context
{
State* state_;
public:
explicit Context(State* state);
void TransitionTo(State* newState);
};
Context::Context (State* state): state_ (nullptr)
{
this->TransitionTo(state);
}
void Context::TransitionTo(State* newState)
{
std::cout <<"Requesting state transition to " << newState->stateName<<"\n";
std::string previous_state_name = "None";
if (this->state_ != nullptr)
{
previous_state_name = this->state_->stateName;
delete this->state_;
}
this->state_ = newState;
std::cout << "State changed from "<< previous_state_name << " to "<< this->state_->stateName << "\n";
this->state_->set_context(this);
}
/* State class and method implementation */
class State
{
protected:
Context* context_;
public:
std::string stateName;
void set_context(Context* newContext);
virtual ~State();
};
State::~State()
{
std::cout << stateName <<" state deleted \n";
delete context_ ;
}
void State::set_context(Context *newContext)
{
this->context_ = newContext;
}
/* Declaring different states which are derived from State */
class HappyState : public State
{
public:
HappyState();
};
HappyState::HappyState()
{
stateName = "Happy";
}
class NeutralState : public State
{
public:
NeutralState();
};
NeutralState::NeutralState()
{
stateName = "Neutral";
}
class SadState : public State
{
public:
SadState();
};
SadState::SadState()
{
stateName = "Sad";
}
/* Test the implementation */
int main()
{
Context* ctx = new Context(( new NeutralState()));
ctx->TransitionTo(new HappyState());
ctx->TransitionTo(new SadState());
return 0;
}
When I run this code, I am getting following output: Output snapshot
CodePudding user response:
I found the mistake which was indeed a very silly one.
I was deleting the context_ in ~State() which deleted my original context.
CodePudding user response:
I can't quite figure out why you get a double free. But here are some pointers. Use smart_pointers to avoid senarios like this, e.g unique_ptr and shared_ptr. I'd make a getStateName func in State, instead of keeping stateName as public.