Memory Leak Prevention


Pickle

Mega GP Mania
Joined
May 30, 2006
Messages
5,518
Location
Detroit, Michigan
Website
Visit site
This is for those C++ experts out there. I understand class's and that there is a destructor that is called when the class is out of scope. What if there is a pointer to that class, can i just delete the pointer and all of the memory is free? Heres what im doing:

Declare the pointer
CODE
CGraphic* gfxCrew = NULL;

Assign the pointer
CODE
else if( strLine.find("#crew_gfx") == 0 ) gfxCrew = new CGraphic( ReadGraphicParameters( strLine ) );

delete the poiner
CODE
delete gfxCrew;


Can the class mempry be reclaimed?
 
To be quite honest, this is something that I'm not 100% sure about either... To make sure when I use new and delete, I call a cleanup function inside the class just before I delete the object. I also place a call to this function from within the destructor.

I keep forgetting to step through with the debugger to see if the destructor is called when you delete a pointer to a class... I think it should be, but I get the feeling that it's not! :p

Any super guru care to clarify? :)
 
PokeParadox said:
I keep forgetting to step through with the debugger to see if the destructor is called when you delete a pointer to a class... I think it should be, but I get the feeling that it's not! :p
Yeah i tried the delete and to see if it the debugger picked up a breakpoint in the destructor and it didnt, thus the question.
 
Last edited by a moderator:
The whole point of a dtor is to not have to manually call a clear-out function, since that is something easily forgotten. However, it is still common .. ie: sometimes it makes sense to do it.

Still, it gets hairy..

Remember, the compiler kills the declared thing when it goes out of scope. IF you declare..

MyClass poop;

Then do not delete ( &poop ) since its allocated on the stack, meaning the compiler will due the delete for you, and thus if you delete it first.. the compiler will delete it _again_, likely causing issues.

Id you allocate with new, then you must delete it.

Do your cleanup in the delete.

The tricky stuff is when your objects are sharing stuff bertween them.. like, if you have two classes, with points to the same thing (a char* say), and thus you might want to have a clear() function to kill that, but your dtor just leave it since it doesn't kow if its being used somewhere else etc..

jeff
 
Its all about ownership of allocated memory. If you create something on the stack then the object's destructor is called at end of scope. There can be no memory leak here since there was no memory allocated, just stack space. If you create something on the heap (i.e. new) then you should delete it when no-one needs the object. Normally you have some concept of who owns the object, e.g. by keeping a std::auto_ptr or similar to it. Of course once its gone then no-one else should be pointing (or referencing, same difference) it. If there is a real case where ownership isn't clear - i.e. no idea when to free, just when there are no pointers left I sugget using a smart pointer (or GC). For example TR1::shared_ptr or boost::shared_ptr if you have an old compiler...

Thanks,

Mark
 
You may want to look at RAII objects:
http://en.wikipedia.org/wiki/Resource_Acqu..._Initialization

What the delete keyword does is call the destructor of the object and then free the allocated memory.

In my last project, I have something similar for SDL surfaces:
CODE
//! A wrapper for the SDL surface to insure that it is cleaned up correctly

#ifndef SURFACEWRAPPER_H
#define SURFACEWRAPPER_H

#include <SDL/SDL.h>

namespace GfxModule
{
class SurfaceWrapper
{
public:
//! Pointer to SDL_Surface
SDL_Surface *_Surface;

//! Standard Constructor. Nulls the pointer
SurfaceWrapper(void) : _Surface(0)
{
// Intentionally left blank
}

//! Standard Destructor. Checks if the pointer is Null, if not, it frees the surface
~SurfaceWrapper(void)
{
if(_Surface)
SDL_FreeSurface(_Surface);
}
};
}

#endif // SURFACEWRAPPER_H

/*
History
=======
2006-06-30: Moved code from the cpp file to here
2006-06-15: Class removed from SurfaceManager and pasted here. Added new functionality.
*/
 
yaustar said:
You may want to look at RAII objects:
http://en.wikipedia.org/wiki/Resource_Acqu..._Initialization

What the delete keyword does is call the destructor of the object and then free the allocated memory.

In my last project, I have something similar for SDL surfaces:



Yeah im doing the same thing with the class in the example I did above. But does delete follow a reference to the real object? By deleting the reference (the pointer) is the SDL_surface noe free?
 
Last edited by a moderator:
Thanks for the feedback.

Ive talked to someone I work thats pretty good with C++ and he confirmed that the delete should be calling the destructor. Also due to the way the destructor is compilied it may not be easy to set a breakpoint, he gave the alternative of putting a simple command line output to confirm it, which I think I will try.
 
CODE
~SurfaceWrapper(void)
{
} // Put break point here


That normally works in Visual Studio, I can't remember in Code::Blocks.
 
yaustar said:
CODE
~SurfaceWrapper(void)
{
} // Put break point here
That normally works in Visual Studio, I can't remember in Code::Blocks.


tried that, didnt work.
But I did put in a line to output to file and it does in fact work. So it confirms what I expected as long as you delete the the pointer the destructor of the class object being pointed to does in fact get released. Theres no need to call a function before deleting the pointer.
 
Last edited by a moderator:
Back
Top