Jump to content
  • Advertisement
Sign in to follow this  
sheep19

memory leak?

This topic is 2586 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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.

stage = new Intro(/*parameters*/);


Then, inside the intro stage, I press ESCAPE which pauses, and then "Exit to Menu", which exits to the menu and frees the memory.

delete stage;
stage = NULL;


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

Intro.h
#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


Intro.cpp
#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 = 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.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->FireAt(starPositions.x, starPositions.y);
timePassed = hge->Random_Float(0, RESPAWN_TIME);
}
}

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

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->Update(dt);
timePassed += dt;

if( timePassed > RESPAWN_TIME )
{
timePassed = 0.0f;
starPositions.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->MoveTo(starPositions.x, starPositions.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->Render();
}

void Intro::HandleInput()
{
}


Any ideas?

Share this post


Link to post
Share on other sites
Advertisement
Is the destructor in Stage virtual?
Base class' destructor should be virtual function, otherwise, you can expect memory leak.

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

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.
With his code, if stage does not have a virtual destructor, then Intro's destructor will never be run at allStage* stage = new Intro(/*parameters*/);
delete stage;
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

Is the destructor in Stage virtual?
Base class' destructor should be virtual function, otherwise, you can expect memory leak.


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!