GC can collect object allocated in function, despite a pointer to the object living on?
Chris Cain via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Aug 16 15:43:20 PDT 2014
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";
}
}
More information about the Digitalmars-d-learn
mailing list