On Saturday, 16 August 2014 at 22:36:51 UTC, 岩倉 澪 wrote:
void changeState(){
     if(nextState != "WaitState" && nextState != "ExitState"){
         auto newState = cast(IState)
Object.factory("game.states."~nextState);
         import std.exception;
         enforce(newState);
// !!!!!!!!!!!!!!!
         currentState = &newState;
// !!!!!!!!!!!!!!!
         nextState = "WaitState";
     }
}

However, it appears that the changeState function has a bug.
I believe the problem is that when changeState returns, newState
gets garbage collected, despite currentState pointing to it.
I come from a C++ background, so I am not used to garbage
collection.
Normally the changeState function would explicitly free the old
state, and allocate the new one.

Am I correct that newState is liable to be collected after
changeState returns?
Is there an easy fix?
Is my design fundamentally flawed within the context of garbage
collection?
If so, what kind of design would you recommend instead?

This is actually not garbage collection. &newState is making a
pointer to a reference that is located on the stack (that is,
when you return from that function
you now have a pointer that may at any time become overwritten
and made invalid.)

As it turns out, interfaces/classes in D are already reference
types, so you can just do something like this:

IState currentState; // reference to an IState

void changeState(){
      if(nextState != "WaitState" && nextState != "ExitState"){
          auto newState = cast(IState)
Object.factory("game.states."~nextState);
          import std.exception;
          enforce(newState);
          currentState = newState; // changed
          nextState = "WaitState";
      }
}

Reply via email to