Memory Leaks
I have a question about memory leaks.
My program declares an instance of a class in the main function. This class contains several objects that need to be cleaned up when the class is destroyed. So, the code to clean it up is located in the destructor, which is called when the instance goes out of scope. But, it doesn't go out of scope until main is closed, which is after the program has exited. Therefore, one the destructor is called, it throws an access violation.
So, is this correct, and is it a problem?
Mmm.
The deconstructor should get called at the end of the program, and it should not throw an access violation (atleast, it does not when I do what your doing [if I understand you correctly]). Might I suggest you try Debugging it? Other then that, some code might help.
Chad.
The deconstructor should get called at the end of the program, and it should not throw an access violation (atleast, it does not when I do what your doing [if I understand you correctly]). Might I suggest you try Debugging it? Other then that, some code might help.
Chad.
have you tried calling the destructor before your program closes?
I.E. class.~class();?
hope that works.
=-Cory-=
I.E. class.~class();?
hope that works.
=-Cory-=
I had the same problem with singletons. Make a debug function in your singleton class:
in contructor you should have something like this:
CSingleton::CSingleton()
{
m_pSingleton = this;
etc...
}
make something like this:
static void dbgDestroy(void)
{
if(m_pSingleton != NULL)
{
delete m_pSingleton;
m_pSingleton = NULL;
}
}
in the last line of code, before you call _CrtDumpMemoryLeaks insert:
CSingleton::dbgDestroy(); <- Leaves the scope
_CrtDumpMemoryLeaks();
Beware, you have to create your singleton with "new" in order to be able to destroy it whenever you want.
in contructor you should have something like this:
CSingleton::CSingleton()
{
m_pSingleton = this;
etc...
}
make something like this:
static void dbgDestroy(void)
{
if(m_pSingleton != NULL)
{
delete m_pSingleton;
m_pSingleton = NULL;
}
}
in the last line of code, before you call _CrtDumpMemoryLeaks insert:
CSingleton::dbgDestroy(); <- Leaves the scope
_CrtDumpMemoryLeaks();
Beware, you have to create your singleton with "new" in order to be able to destroy it whenever you want.
0) DO NOT CALL THE DESTRUCTOR EXPLICITLY. You would only do this if you "called the constructor explicitly" (a simplification) as well, via 'placement new'. Anything else is serious bad mojo in the undefined behaviour sense.
1) The question as posed is not about memory leaks, and if the destructor throws an access violation, the problem is with the code of the destructor.
I *think* what you meant is that you have put in some kind of memory leak detection, which you call at the end of main(), and it trips an assertion saying "omg memory leak" because the object hasn't been destructed yet (because main() hasn't ended yet).
This is correct behaviour, and is not "a problem" unless you want accurate detection of leaks. But I assume you do :)
The simplest solution is probably to make use of an anonymous scope:
The provided solution for singletons is really only relevant if you have a static or global object that needs to be destructed. Even then, you may consider instantiating the global object as a local of main(), and exposing a global *pointer to main's variable*. Then, client code accesses the singleton via the global pointer, and the singleton's dtor is called as a result of the object falling out of its scope (the anonymous scope within main()).
1) The question as posed is not about memory leaks, and if the destructor throws an access violation, the problem is with the code of the destructor.
I *think* what you meant is that you have put in some kind of memory leak detection, which you call at the end of main(), and it trips an assertion saying "omg memory leak" because the object hasn't been destructed yet (because main() hasn't ended yet).
This is correct behaviour, and is not "a problem" unless you want accurate detection of leaks. But I assume you do :)
The simplest solution is probably to make use of an anonymous scope:
int main() { { // <-- you don't need any if/for/while/etc. construct in order to introduce // a new level of scope! ThingWithComplexDestructor x; do_lots_of_stuff(); } // <-- this is the end of x's scope, so its destructor is called here detect_memory_leaks(); // <-- assuming the destructor works properly, // there should be no leak detected here.}
The provided solution for singletons is really only relevant if you have a static or global object that needs to be destructed. Even then, you may consider instantiating the global object as a local of main(), and exposing a global *pointer to main's variable*. Then, client code accesses the singleton via the global pointer, and the singleton's dtor is called as a result of the object falling out of its scope (the anonymous scope within main()).
It uses SDL_ttf to draw text to the screen. I tried calling the destructor befor the end of the program, which prevented it from causing access violations, but caused the program to not exit ie return a value and cause the debugger to stop. When I put nothing into the destructor, no access violations.
I also tried adding an extra scope inside main which contains everything except for return 0; So the problem may be something else
The relevant code:
I also tried adding an extra scope inside main which contains everything except for return 0; So the problem may be something else
The relevant code:
#include "SDL\SDL.h"#include "SDL\SDL_ttf.h"#include "Text.h"int main(int argc, char* argv[]){ SDL_Surface *screen; SDL_Event e; bool running; Text text; if(SDL_Init(SDL_INIT_VIDEO)<0) { return 1; } if(TTF_Init()<0) { return 1; } screen=SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); if(screen==NULL) { return 1; } SDL_WM_SetCaption("Testing", NULL); /**OBJECT INITIALIZATION**/ text.Load(".\\fonts\\vera.ttf", 16); text.SetText("testing"); text.SetColour(255, 0, 0); /**LOOP**/ running=true; while(running) { /**DRAWING**/ text.Write(screen); SDL_Flip(screen); /**EVENT HANDLER**/ SDL_PollEvent(&e); switch(e.type) { case SDL_QUIT: running=false; break; case SDL_KEYUP: switch(e.key.keysym.sym) { case SDLK_ESCAPE: running=false; break; }//end keysymbol handler }//end event handler }//end loop SDL_FreeSurface(screen); SDL_Quit(); TTF_Quit(); return 0;}destructor for text:Text::~Text(){ SDL_FreeSurface(txtSurface); TTF_CloseFont(font);}member variables for text:TTF_Font *font;std::string text;SDL_Rect destRect;SDL_Colour fontColour;SDL_Surface *txtSurface;
Ok without trying to sound rude I really wish people would read the sdl docs. You do not own the SDL_surface which is created by SDL_SetVideoMode and you should not clean it up using SDL_FreeSurface.
http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode
Quote:... The surface returned is freed by SDL_Quit and should not be freed by the caller. Note: This rule includes consecutive calls to SDL_SetVideoMode (i.e. resize or rez change) - the pre-existing surface will be released automatically.
http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode
int main(int argc, char* argv[]){ if(SDL_Init(SDL_INIT_VIDEO)<0) // blah blah all the other initializers { Text text; // all the other stuff } SDL_FreeSurface(screen); TTF_Quit(); SDL_Quit(); return 0;}
Thanks for the help, adding the second scope and eliminating the SDL_FreeSurface(screen) fixed it.
Quote:Original post by HJSimpson
It uses SDL_ttf to draw text to the screen. I tried calling the destructor befor the end of the program, which prevented it from causing access violations, but caused the program to not exit ie return a value and cause the debugger to stop. When I put nothing into the destructor, no access violations.
Then the access violation is nothing to do with a "memory leak" (that's forgetting to clean up something you should) and is a plain old access violation having to do with double-deletion (that's trying to clean up something again when you shouldn't) - a side effect of the SDL_FreeSurface() call on something you're not supposed to SDL_FreeSurface().
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement