Thread: Problem with destructors.

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    97

    Problem with destructors.

    I'm working on a slightly complex application and I have a problem. A few destructors are not getting called when the program quits.
    I have a few classes, all are initialized just fine, the program runs fine, no crashes or anything. The problem is that when I quit I find a lot of memory leaked. I checked everything and I was able to fix some of them, the problem was that I was not freeing those variables. But I have a problem where memory is leaked at exit even though I free the momory in the destructor. Basically its
    OBJECT_MANAGER which manages all the Objects, then here are loaded the Objects from a file, when the text is parsed a new OBJECT is created. In the OBJECT class there are different classes depending on the parsed text. If its is a sound then SOUND_MANAGER is called and depending on the sound format it may call the MP3_CLASS or OGG_CLASS. The problem is that the OBJECT destructor is not called at exit so nothing is freed, I end up with a lot of memory leaked. How can I make sure that the destructor of each class gets called?

    THANKS!

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    82
    Quote Originally Posted by Hulag
    A few destructors are not getting called when the program quits.
    I don't have much experience, but that seems suspect. Assuming the code compiles, a destructor is called everytime an object goes out of scope. The source of your problem would be that the wrong destructor gets called (ie a default constructor), or problem within the way the destructor deallocates memory.

    I'd suggest posting the code, as most likely memory is allocated somewhere within one of the classes, but ignored by the appropriate destructor.

  3. #3
    Registered User
    Join Date
    Aug 2001
    Posts
    223
    can you post some of your code where you are creating the objects. This may help clarify the situation.
    zMan

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    As stated before, it's hard to tell when you don't have source to look at. However, if you are using inheritance then you will want to look into using virtual destructors. Declare your base class destructors as virtual so that the derived class destructors will be called properly.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> The problem is that the OBJECT destructor is not called at exit so nothing is freed, I end up with a lot of memory leaked.

    If you used 'new' to allocate it, don't expect the destructor to be called when the program exits - it won't. Instead, just create a global instance (outside of main) as a stack variable. At that point, if the destructor isn't called then there is something very wrong with the compiler you are using.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Oct 2003
    Posts
    97
    Unfortunaly the code is just too much to just paste, and I can't release the whole code either. But I will try to explain my problem.

    First, I start the OBJECT_MANAGER
    Code:
    OBJECT_MANAGER::StaticInstance()->Initiate(); // The StaticInstance is to avoid making copies, only one OBJECT_MANAGER in the whole program.
    The Initiate() function loads the objects from a file and puts them in a temporary structure which basically holds a property name and value for every object. Then then from that info, the OBJECTs are created.

    Code:
    for (i = 0; i < num_objects; ++i)
    {
    	OBJECT * newObject=new OBJECT;
    	if(!newObject)
    	{
    		LOGGING::StaticInstance()->Error("FAILURE!");
    		return 0;
    	}
    	newObject->origin = object_vec3(i, "origin"); // Position of the object.
    	newObject->angle = object_float(i, "angle"); // Angle faced by the object.
    	const char *objectclass_val = object_value(i, "classname"); // Determine what type of object it is.
    	if (!stricmp(objectclass_val, "sound")) // if it is a sound file
    	{
    		newObject->filename = object_value(i, "filename");
    		if (strcmp(newObject->filename, "") != 0)
    		{
    			newObject->SoundManager = new SOUND_MANAGER; 
    			newObject->SoundManager->SoundData = SOUND_MANAGER::StaticInstance()->LoadFile(newObject->filename);
    		}
    	}
    	// Then other object_classes are processed.
    }
    Ok, now on the LoadFile
    Code:
    SOUND * newSound;
    
    int filenameLength=strlen(filename);
    if( 	strncmp(filename+filenameLength-3, "MP3", 3)==0 || strncmp(filename+filenameLength-3, "mp3", 3)==0)
    {
    	newSound=new MP3_SOUND;
    }
    else if(strncmp(filename+filenameLength-3, "OGG", 3)==0 || strncmp(filename+filenameLength-3, "ogg", 3)==0)
    {
    	newSound=new OGG_SOUND;
    }
    else
    {
    	LOGGING::StaticInstance()->Error("FAILURE!");
    	return -1;
    }
    newSound->Load();
    
    sounds.push_back(newSound);
    
    return sounds.size()-1;
    Now, I have destructors for all my classes. For example the constructor and destructor for OBJECT look something like this
    Code:
    OBJECT() : SoundManager(NULL)
    {}
    
    ~OBJECT()
    {
    	if(SoundManager)
    		delete SoundManager;
    	SoundManager;
    }
    The problem that it doesn't even get called, which means that none of the other classes inside SoundManager will get called either.
    How can I fix that? THANKS!

    PS: Don't worry for errors or if it compiles or not, I just made a quick example to explain, its not the actual code.

  7. #7
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Code:
    OBJECT * newObject=new OBJECT;
    Do you ever call delete on that? As Sebastiani said, the destructor won't automatically be called when it goes out of scope.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  8. #8
    Registered User
    Join Date
    Oct 2003
    Posts
    97
    I completly forgot to answer the thread, sorry about that. The problem was actually both cases, sometimes I didn't delete the new objects, and sometimes I needed to use virtual destructors. Thanks to everybody for helping me go from 16MB leaked per sound to leaking exactly 0 bytes in the whole program(there are other nested leaks that have nothing to do with my code but some DLLs I use).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM