memory leak?

Started by
6 comments, last by ryan20fun 12 years, 10 months ago
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?
Advertisement

I am checking the memory consumption from task manager

This is an inherently unreliable way to look for memory leaks. Try this instead.
Is the destructor in Stage virtual?
Base class' destructor should be virtual function, otherwise, you can expect memory leak.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

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.
Wisdom is knowing when to shut up, so try it.
--Game Development http://nolimitsdesigns.com: Reliable UDP library, Threading library, Math Library, UI Library. Take a look, its all free.

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.
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.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

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:
BreakPoints are very helpfull when im trying to find out why something is not working

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.

This topic is closed to new replies.

Advertisement