Sign in to follow this  
sheep19

memory leak?

Recommended Posts

Hi. I am making a game which will consist of several stages. Right now I'm testing the menu and the intro stage. When in I press "Start" in the menu, memory is allocated for the intro stage using new.
[code]
stage = new Intro(/*parameters*/);
[/code]

Then, inside the intro stage, I press ESCAPE which pauses, and then "Exit to Menu", which exits to the menu and frees the memory.
[code]
delete stage;
stage = NULL;
[/code]

The problem is that the memory is not getting freed!!! (I am checking the memory consumption from task manager)

[b]Intro.h
[/b][code]#ifndef STAGE_INTRO_H
#define STAGE_INTRO_H

#include <hgesprite.h>
#include <hgeresource.h>
#include <hge.h>
#include <hgeparticle.h>

#include <cstdint>
#include <memory>

#include "Stage.h"
#include "hgePoint.h"

class Intro : public Stage
{
public:
Intro(hgeResourceManager *_resourceManager);
~Intro();

void Update(float dt);
void Render();
void HandleInput();
const char *StageName() const { return "Intro"; }

private:
Intro(const Intro &intro);
Intro &operator = (const Intro &intro);

HGE *hge;
hgeSprite *background, *ship;
hgePoint shipPos;
float shipScale;

hgeResourceManager *resourceManager;
static const uint16_t STARS = 500;
hgeParticleSystem *stars[STARS];
hgePoint starPositions[STARS];
static const float RESPAWN_TIME;
float timePassed[STARS]; // time passed since respawned -> respawns every 2 seconds
};

#endif[/code][b]

Intro.cpp
[/b][code]#include "Stage.h"
#include "Intro.h"

const float Intro::RESPAWN_TIME = 2.0f;

// constructor
Intro::Intro(hgeResourceManager *_resourceManager) : hge(hgeCreate(HGE_VERSION)), resourceManager(_resourceManager), shipScale(1.0f)
{
resourceManager->Precache(1);
background = resourceManager->GetSprite("intro_background");
ship = resourceManager->GetSprite("spaceship");

shipPos.Set(-ship->GetWidth() * 1.1f, hge->System_GetState(HGE_SCREENHEIGHT)*0.5f - ship->GetHeight() * 0.5f);

if( !background ) { hge->System_Log("Intro::Intro -> background could not be loaded"); exit(-1); }
if( !ship ) { hge->System_Log("Intro::Intro -> ship could not be loaded"); exit(-1); }

for(auto i = 0; i < STARS; ++i)
{
try
{
stars[i] = new hgeParticleSystem("data/particles/very_small_star.psi", resourceManager->GetSprite("star_particle"));
}
catch(...)
{
hge->System_Log("In Intro::Intro : Memory for hgeParticleSystem (%d of %d) could not be allocated", (int)i, (int)STARS);
exit(-1);
}
starPositions[i].Set((float)hge->Random_Int(0.0f, hge->System_GetState(HGE_SCREENWIDTH) - 1), (float)hge->Random_Int(0, hge->System_GetState(HGE_SCREENHEIGHT) - 1));
stars[i]->FireAt(starPositions[i].x, starPositions[i].y);
timePassed[i] = hge->Random_Float(0, RESPAWN_TIME);
}
}

// destructor
Intro::~Intro()
{
for(auto i = 0; i < STARS; ++i)
delete stars[i];

resourceManager->Purge(1);
hge->Release();
}

void Intro::Update(float dt)
{
shipPos.x += 25 * dt;
shipScale -= 0.0005f;

for(auto i = 0; i < STARS; ++i)
{
stars[i]->Update(dt);
timePassed[i] += dt;

if( timePassed[i] > RESPAWN_TIME )
{
timePassed[i] = 0.0f;
starPositions[i].Set((float)hge->Random_Int(0.0f, hge->System_GetState(HGE_SCREENWIDTH) - 1), (float)hge->Random_Int(0, hge->System_GetState(HGE_SCREENHEIGHT) - 1));
stars[i]->MoveTo(starPositions[i].x, starPositions[i].y);
}
}

}

void Intro::Render()
{
background->Render(0, 0);
ship->RenderEx(shipPos.x, shipPos.y, 0, shipScale, shipScale);

for(auto i = 0; i < STARS; ++i)
stars[i]->Render();
}

void Intro::HandleInput()
{
}[/code][b]

Any ideas?
[/b]

Share this post


Link to post
Share on other sites
[quote name='sheep19' timestamp='1306106073' post='4814374']
I am checking the memory consumption from task manager
[/quote]
This is an inherently unreliable way to look for memory leaks. [url="http://msdn.microsoft.com/en-us/library/e5ewb1h3%28v=vs.80%29.aspx"]Try this instead[/url].

Share this post


Link to post
Share on other sites
hmmmm.

I would suggest adding some output to console debug code to your allocations and deallocations so you can try to match up what is being allocated with what isn't. If this is a small program, it should be easy for you to figure it out.and it should be apparent very quickly what isn't happening, then you can figure out why it isn't happening.

Share this post


Link to post
Share on other sites
[quote name='smasherprog' timestamp='1306123244' post='4814440']
hmmmm. unfortunately, a virtual function is likely not the problem, and having a virtual destructor in the base class doesn't imply anything about freeing any memory. Typically, a base class should free up any memory that it allocated.[/quote]With his code, if stage does not have a virtual destructor, then Intro's destructor will never be run at all[code]Stage* stage = new Intro(/*parameters*/);
delete stage;[/code]When this code runs, [font="Courier New"]new[/font] will allocate [font="'Courier New"]sizeof(Intro)[/font] bytes and then call [font="Courier New"]Stage::Stage()[/font] and [font="Courier New"]Intro::Intro()[/font], but then when [font="Courier New"]delete[/font] is called it will only call [font="Courier New"]Stage::~Stage()[/font] but NOT [font="Courier New"]Intro::~Intro()[/font]. Furthermore, it will pass an invalid size (i.e. [font="Courier New"]sizeof(stage)[/font] instead of [font="Courier New"]sizeof(Intro)[/font]) to the deallocation function.

Share this post


Link to post
Share on other sites
Other than what has been mentioned, what jumped out at me was the use of a try-catch(...) inside a loop. There isn't really a need for it to be inside the loop, that just causes more work for setting up the exception handling mechanism each time through the loop. Whilst this isn't related to your problem, I suggest moving the try-catch outside of the loop.
Better still, does the catch need to be inside this constructor at all?
Another good idea would be to just catch std::bad_alloc.

Share this post


Link to post
Share on other sites
[quote name='wqking' timestamp='1306116296' post='4814416']
Is the destructor in Stage [b]virtual[/b]?
Base class' destructor should be virtual function, otherwise, you can expect memory leak.
[/quote]

That was the problem - it wasn't! Thank you!!:lol:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this