Crystal Space
Welcome, Guest. Please login or register.
April 25, 2014, 01:58:21 am

Login with username, password and session length
Search:     Advanced search
8990 Posts in 2037 Topics by 7628 Members
Latest Member: Majstersztyk1989
* Home Help Search Login Register
+  Crystal Space
|-+  Crystal Space Development
| |-+  Support
| | |-+  Objects don't get destroyed at application exit
« previous next »
Pages: [1] Print
Author Topic: Objects don't get destroyed at application exit  (Read 2295 times)
GangMan
Newbie
*
Posts: 6

18456839 gangman2000@hotmail.com
View Profile WWW
« on: January 10, 2006, 11:23:48 am »

Okay, here's another (newbie?) question connected with reference counting: In order to make some important objects in my game - such as instances of iLoader and iEngine - available also to other classes than my main application class, I decided to write some kind of "singleton wrapper" which holds exactly one instance of each these objects and makes them available throught static methods. The header file looks like this:

Code:
class ComponentRegistry
{
public:
   static void setEngine(csRef<iEngine> engine);
   static void setLoader(csRef<iLoader> loader);

   static csRef<iEngine> getEngine();
   static csRef<iLoader> getLoader();

private:
   static csRef<iEngine> mEngine;
   static csRef<iLoader> mLoader;
};

The implementation was done in this way:

Code:
#include "ComponentRegistry.h"

csRef<iEngine> ComponentRegistry::mEngine = 0;
csRef<iLoader> ComponentRegistry::mLoader = 0;

void ComponentRegistry::setEngine(csRef<iEngine> engine) {
   mEngine = engine;
}

csRef<iEngine> ComponentRegistry::getEngine() {
   return mEngine;
}

void ComponentRegistry::setLoader(csRef<iLoader> loader) {
   mLoader = loader;
}

csRef<iLoader> ComponentRegistry::getLoader() {
   return mLoader;
}

(I know this could be done inline as well). So here's the point: Instead of creating my engine and assigning it to a member variable such as mEngine = csQueryRegistry<iEngine>(GetObjectRegistry()); i'm now using my setter method: ComponentRegistry::setEngine(csQueryRegistry<iEngine>(GetObjectRegistry()));. Now the wrapper is initialized and I can access my engine object for example like this: ComponentRegistry::getEngine()->SetLightingCacheMode(0);

Imagine the same behaviour for the loader instance. It all works perfectly fine until I quit the application. Then I get reported lots of unreleased instances of things like crystalspace.engine.3d, crystalspace.graphic.image.io.[imageformats] and so on. There's also an exception in the destructor of ref.h when it comes to executing CSREF_TRACK_DECREF(...).

So I'm not quite sure what's happening here and why objects are not properly destructed. I noticed when manually calling DecRef() on those two objects in the destructor of my application all but one single unreleased instances are gone - the exception still occurs though. So maybe I have a total misconception of some basic c++ rules here or I'm using the reference couting in a wrong way.

Any help would be appreciated.

TIA
GangMan
Logged
jorrit
Administrator
Hero Member
*****
Posts: 1704


View Profile
« Reply #1 on: January 10, 2006, 11:32:11 am »

They are not properly destructed because you are storing your csRef's in static variables. These variables are not cleared automatically so they simply keep there ref forever. Best is to avoid static variables (especially static variables that are references).

Greetings,
Logged
GangMan
Newbie
*
Posts: 6

18456839 gangman2000@hotmail.com
View Profile WWW
« Reply #2 on: January 10, 2006, 11:51:29 am »

Thanks for the info.
So would you recommend adapting the class to a singleton class that holds a static reference to itself but keeps the other objects (loader, engine) as normal members or adapting it to a regular class with non-static methods where you just create one instance and pass a pointer of this instance to all classes that need access to the loader or the engine (I think this would be similar to the solution shown in http://community.crystalspace3d.org/forum/index.php/topic,652.0.html)?
The first solution of course means that the singleton class itself would have to be destroyed (since it's again static), the second one just doesn't seem to be so comfortable since I have to pass on the instance of my ComponentRegistry to each class that wants to use it.

That's why I initially chose the solution I've displayed earlier since I think it's quite clear and good to use (except for the errors).

GangMan
Logged
jorrit
Administrator
Hero Member
*****
Posts: 1704


View Profile
« Reply #3 on: January 10, 2006, 11:55:07 am »

Thanks for the info.
So would you recommend adapting the class to a singleton class that holds a static reference to itself but keeps the other objects (loader, engine) as normal members or adapting it to a regular class with non-static methods where you just create one instance and pass a pointer of this instance to all classes that need access to the loader or the engine (I think this would be similar to the solution shown in http://community.crystalspace3d.org/forum/index.php/topic,652.0.html)?
The first solution of course means that the singleton class itself would have to be destroyed (since it's again static), the second one just doesn't seem to be so comfortable since I have to pass on the instance of my ComponentRegistry to each class that wants to use it.

That's why I initially chose the solution I've displayed earlier since I think it's quite clear and good to use (except for the errors).

GangMan

Well if you use a static singleton the problem stays the same. The singleton will not get destroyed (unless you add manual code to destroy it when your application closes) and the refs will not get released as well.

Personally I think passing along the ComponentRegistry is the cleanest solution. What I would do is make the ComponentRegistry a member of your main application class. Nearly everything will have a reference to that anyway I suppose?

Greetings,
Logged
GangMan
Newbie
*
Posts: 6

18456839 gangman2000@hotmail.com
View Profile WWW
« Reply #4 on: January 10, 2006, 03:37:51 pm »

Thanks for your opinion. I guess this is the best solution then. I'll try it and come back whining when I run into other problems Wink

GangMan
Logged
Pages: [1] Print 
« previous next »
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 6.084 seconds with 15 queries.