   Singleton instance added to vector goes out of scope?
  Hi Gamedev!I am working on a game state management framework for my next project, inspired by various online tuts and guides, one of them being this one.As you can see, the different GameStates are singletons that pass their address when you want to get them:static IntroState* getInstance() { return &mIntroState; }If I somewhere in the framework asks my GameStateManager to change state to, say the intro (logo is shown etc.), and add the singleton instance to a vector of GameState pointers like this:States.push_back(gs); // gs is GameStateIntro::GetInstance()Does gs go out of scope when the function returns? Before returning from the function I print the size of the vector to the console window. After the function returns I print the size again. Here is the output:No. States: 1No. States: 0So it looks like it goes out of scope. I usually create my singletons as pointers using new and delete thus making sure the singleton does NOT go out of scope, unless I screw up and delete it. This might be the solution, but I really want to know if this method works.Right now, the program does not show what it is supposed to since it has no states in the vector to update/draw etc.I'll post more of my code if you need it.Thanks in advance! :)   
  * in before twelve page discussion why singletons are evil *Quote:Original post by NordCoderDoes gs go out of scope when the function returns?It's pointing to some global object, so I guess no.Quote:So it looks like it goes out of scope.No, it looks like it's removed from the vector somehow. A vector just holds data, it doesn't validate it. You can add as many uninitialized or invalid pointers as you want. Perhaps you are clearing the vector somewhere in our code?   ;  Where is States stored? It sounds like you have 2 copies of States, and you're adding gs to a local one that is going out of scope.   ;  @ Wan: Quote:It's pointing to some global object, so I guess no.Its a static object defined in the GameStateIntro class: static GameStateIntro gamestateintro; if that is what you mean.Doublechecked the possibility of somehow deleting the content of the vector. Here is the code for changing states:void GameStateManager::ChangeState(GameState* gs){if(gs){if(!States.empty()){int size = States.size();for(int i = 0; i < size; i++){if(States.back()){States.back()->UnLoad();States.pop_back();}}}States.clear();States.push_back(gs);if(!States.back()->Load()) // Invalid state, quit application{GameStateManager::GetManager().Quit();}}else{printf("Invalid gamestate!");}printf("No. states: %d\n", States.size());}Between adding the state (gs) and returning from the function (where it encounters another printf() statement which prints 0), no deletion occurs, as far as I can see.@ Ariste:The vector is stored in the GameStateManager class:class GameStateManager{public:~GameStateManager();static GameStateManager GetManager();void ChangeState(GameState* gs);void PushState(GameState* gs);void PopState();void Quit(); // Tells the 'Game' to quitvoid PassEvent(SDL_Event& event);void UpdateStates(int dt);void DrawStates();void CleanUpStates();GameState* GetCurrentState() const;int GetNoStates() const;bool IsRunning() const;private:GameStateManager(); // hidden constructorstatic GameStateManager Gsm;vector<GameState*> States;bool Running;};By the looks of it, I am only dealing with a single version of States throughout the code.In addition, here is the call to the ChangeState member function:GameStateManager::GetManager().ChangeState(GameStateIntro::GetInstance());printf("No. states: %d\n", GameStateManager::GetManager().GetNoStates());Hope this helps :)   ;  Have you stepped through the code in a debugger to see exactly where the size of the vector changes?   ;  I have not, since it wouldn't allow to do so. When I say 'break', it tells me that: "No symbols are loaded for any call stack frame. The source code cannot be displayed.". Pressing continue seems to do nothing. I am using Microsoft Visual C++ 2008 Express Edition.However, I may have found the bug. This...GameStateManager GameStateManager::GetManager(){return Gsm;}...should be this:GameStateManager& GameStateManager::GetManager(){return Gsm;}If not, I am passing by value (a copy of Gsm) instead of the actual object. I works now though...Please correct me on this if I am wrong.EDIT: Sorry for the messed code tags. Accidentally wrote  :P   ;  Have you read the link provided by the second poster, on the 12 step program?  It would be a great idea before you develop really bad programming practices which are annoying to break (been there, singletoned that)?   ;  By definition, you cannot add a singleton instance to a vector. Singleton means "there will only be one instance of this class, ever". Putting something into a vector means that you copy it. Copying one instance results in two instances.It appears that what you are really doing is holding a vector of pointers to some base class, and making each derived class a singleton. Further, you are using these classes to represent game states.Well. First off, do you really need a vector of states? Why? So you can "go back" to the previous one? How common is that? Do you need to remember what the previous state was? Isn't it implicit? Is there really more than one "source state" for the current state? Isn't there some other way to figure out what state to go back to? And if you really do need this ability, why not just store a pointer to the previous state (potentially chaining them in an intrusive, singly-linked list - except that you aren't using nearly all that functionality)?And then - what do you gain by making the states singletons? What if I need to enter a state that's already on the stack, but with newly initialized data - and then go back to the old state, with its remembered data, later?And why do game states need to be "managed", anyway? What's wrong with just using the vector - or the state? As a rule, you should be automatically suspicious of any class with a word like "Manager" in its name.Handling states can be done much, much more simply. Consider, for example, the "Run And Return Successor" pattern (Google it).Anyway, "going out of scope" is irrelevant because values are copied into a vector when you add them. In your case, the values are pointers, but that is irrelevant.   ;Quote:Original post by NordCoderHowever, I may have found the bug. This...*** Source Snippet Removed ***...should be this:*** Source Snippet Removed ***If not, I am passing by value (a copy of Gsm) instead of the actual object. I works now though...Please correct me on this if I am wrong.Yep, that would do it :)   ;  @ Mike2343: Sorry, I must be going blind...What link? You mean the "twelve page discussion"?@ Zahlman: Actually, am I just not pointing to the address of the singleton in memory? Since it is a pointer? I didn't fully understand why I needed a vector at first, but consider the following: In the game menu, you click on a button. The button makes a pop-up appear on top of the menu screen (using PushState). Now because of the way the code is written, both the background (the menu) and the pop-up will be updated and drawn, so the menus animations will still run etc., but only the pop-up will receive events, since it is on top of the menu.There might be simpler ways sure, but I REALLY needed to move away from the block of code with if/switch statements and enums :SAnyways, thanks for your input, I'm reading about the run and return successor pattern now.EDIT: So in this pattern, when you run a state you pass as an argument the state it should go to when it quits? Would you then pass the argument as "new GameStateWhatever()" or as a singleton instance or does the latter conflict your previous arguments (copying a singlton kinda violates the idea of a singleton)?@ Ariste: Thanks, I was not entirely sure :)   